Как сделать чат в глобальной сети c++ [закрыт]

169
04 февраля 2021, 18:40
Закрыт. Данный вопрос необходимо конкретизировать. Ответы на него в данный момент не принимаются.

Хотите улучшить этот вопрос? Переформулируйте вопрос так, чтобы он был сосредоточен только на одной проблеме.

Закрыт 1 год назад.

Улучшить вопрос

Есть Server и Client(можно открыть несколько и передавать сообщения от одного другому), работает в локальной сети, как сделать что бы можно было отправлять сообщения в глобальной сети?

// Server

#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#pragma warning(disable: 4996)
SOCKET Connections[100];
int Counter = 0;
enum Packet {
    P_ChatMessage,
    P_Test
};
bool ProcessPacket(int index, Packet packettype) {
    switch (packettype) {
    case P_ChatMessage:
    {
        int msg_size;
        recv(Connections[index], (char*)& msg_size, sizeof(int), NULL);
        char* msg = new char[msg_size + 1];
        msg[msg_size] = '\0';
        recv(Connections[index], msg, msg_size, NULL);
        for (int i = 0; i < Counter; i++) {
            if (i == index) {
                continue;
            }
            Packet msgtype = P_ChatMessage;
            send(Connections[i], (char*)& msgtype, sizeof(Packet), NULL);
            send(Connections[i], (char*)& msg_size, sizeof(int), NULL);
            send(Connections[i], msg, msg_size, NULL);
        }
        delete[] msg;
        break;
    }
    default:
        std::cout << "Unrecognized packet: " << packettype << std::endl;
        break;
    }
    return true;
}
void ClientHandler(int index) {
    Packet packettype;
    while (true) {
        recv(Connections[index], (char*)& packettype, sizeof(Packet), NULL);
        if (!ProcessPacket(index, packettype)) {
            break;
        }
    }
    closesocket(Connections[index]);
}
int main(int argc, char* argv[]) {
    //WSAStartup
    WSAData wsaData;
    WORD DLLVersion = MAKEWORD(2, 1);
    if (WSAStartup(DLLVersion, &wsaData) != 0) {
        std::cout << "Error" << std::endl;
        exit(1);
    }
    SOCKADDR_IN addr;
    int sizeofaddr = sizeof(addr);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(1111);
    addr.sin_family = AF_INET;
    SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL);
    bind(sListen, (SOCKADDR*)& addr, sizeof(addr));
    listen(sListen, SOMAXCONN);
    SOCKET newConnection;
    for (int i = 0; i < 100; i++) {
        newConnection = accept(sListen, (SOCKADDR*)& addr, &sizeofaddr);
        if (newConnection == 0) {
            std::cout << "Error #2\n";
        }
        else {
            std::cout << "Client Connected!\n";
            std::string msg = "Hello. It`s my first network program!";
            int msg_size = msg.size();
            Packet msgtype = P_ChatMessage;
            send(newConnection, (char*)& msgtype, sizeof(Packet), NULL);
            send(newConnection, (char*)& msg_size, sizeof(int), NULL);
            send(newConnection, msg.c_str(), msg_size, NULL);
            Connections[i] = newConnection;
            Counter++;
            CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ClientHandler, (LPVOID)(i), NULL, NULL);
            Packet testpacket = P_Test;
            send(newConnection, (char*)& testpacket, sizeof(Packet), NULL);
        }
    }

    system("pause");
    return 0;
}

// Client

#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <iostream>
#include <string>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#pragma warning(disable: 4996)
SOCKET Connection;
enum Packet {
    P_ChatMessage,
    P_Test
};
bool ProcessPacket(Packet packettype) {
    switch (packettype) {
    case P_ChatMessage:
    {
        int msg_size;
        recv(Connection, (char*)& msg_size, sizeof(int), NULL);
        char* msg = new char[msg_size + 1];
        msg[msg_size] = '\0';
        recv(Connection, msg, msg_size, NULL);
        std::cout << msg << std::endl;
        delete[] msg;
        break;
    }
    case P_Test:
        std::cout << "Test packet.\n";
        break;
    default:
        std::cout << "Unrecognized packet: " << packettype << std::endl;
        break;
    }
    return true;
}
void ClientHandler() {
    Packet packettype;
    while (true) {
        recv(Connection, (char*)& packettype, sizeof(Packet), NULL);
        if (!ProcessPacket(packettype)) {
            break;
        }
    }
    closesocket(Connection);
}
int main(int argc, char* argv[]) {
    //WSAStartup
    WSAData wsaData;
    WORD DLLVersion = MAKEWORD(2, 1);
    if (WSAStartup(DLLVersion, &wsaData) != 0) {
        std::cout << "Error" << std::endl;
        exit(1);
    }
    SOCKADDR_IN addr;
    int sizeofaddr = sizeof(addr);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(1111);
    addr.sin_family = AF_INET;
    Connection = socket(AF_INET, SOCK_STREAM, NULL);
    if (connect(Connection, (SOCKADDR*)& addr, sizeof(addr)) != 0) {
        std::cout << "Error: failed connect to server.\n";
        return 1;
    }
    std::cout << "Connected!\n";
    CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ClientHandler, NULL, NULL, NULL);
    std::string msg1;
    while (true) {
        std::getline(std::cin, msg1);
        int msg_size = msg1.size();
        Packet packettype = P_ChatMessage;
        send(Connection, (char*)& packettype, sizeof(Packet), NULL);
        send(Connection, (char*)& msg_size, sizeof(int), NULL);
        send(Connection, msg1.c_str(), msg_size, NULL);
        Sleep(10);
    }
    system("pause");
    return 0;
}
Answer 1

Такс, если вы хотите сделать так чтобы, вы сидели дома и сервер был у вас на компьютере и к вам кто-либо подсоединился, то так не получится, почему? Потому что у вас IP не уникальный.

Вам нужно пробиться через NAT и ето задача далеко не тривиальная, тем боллее для ТСР протокола (TCP Hole punching ), вообще, для вещей по типу P2P соединения, посмотрите в сторону UPNP протокола.

Если же вам надо загрузить сервер на сервис типа Azure то, здесь задача попроще, так как теоретически у "облака" есть белый IP, что позволит Вам приконектиться, впрочем тут есть еще куча нюансов, таких как фаервол "облака" и так даллее.

http://bford.info/pub/net/rfc5128.txt

READ ALSO
Заменить постояный вызов assert

Заменить постояный вызов assert

Можно как нибудь красивее написать?

126
Не правильно работает функция std::snprintf

Не правильно работает функция std::snprintf

Мне нужно чтобы выводилось Score: 0:0, а выводится так Score: 0Делаю так:

93
Как избежать множественного включения?

Как избежать множественного включения?

Можно ли создать объект класса внутри другого класса не подключая заголовочный файл в header с описанием этого классасумбурно

103
error C3867 C++

error C3867 C++

Пишет error C3867:"std::basic_string,std::allocator>::c_str" Динамические переменные не использую, нужно отсортировать массив строк c[100] в алфавитном порядке

97