Создать P2P-соединение через Интернет с помощью winsockets

БОЛЬШОЕ РЕДАКТИРОВАНИЕ

так что, очевидно, мой вопрос был не так хорош (судя по двум отрицательным голосам и двум заключительным запросам), поэтому я решил полностью переписать его, а также предоставить MCVE, как я надеюсь. Надеюсь, в этот раз я справился лучше.

объяснение

Поэтому я хочу создать простую программу совместного использования экрана, такую ​​как Teamviewer, но только с возможностью совместного использования экрана, чтобы программа была быстрой и простой. Для этой цели я хочу использовать winsocket2 из winapi. Я хотел начать с сетевой части и подумать о фактической съемке экрана позже. Я создал небольшой прототип, который создает два сокета (клиент и сервер), которые соединяются через локальный хост и могут отправлять и получать данные до сих пор. Теперь я хочу установить связи через Интернет. Я думал об этом следующим образом:

  • Программа запускается и проверяет свой общедоступный IP-адрес, через который он может быть доступен через Интернет, и запускает сервер, связанный с этим IP-адресом и портом (возможно, создает идентификатор IP-адреса и порта или чего-то еще)
  • Теперь пользователь может передать этот IP (или ID) другому лицу с другим клиентом, который затем может вставить его в программу (и, возможно, ввести пароль сеанса, как Teamviewer), который затем подключается к первой программе и может получать данные экрана
  • Я хочу сделать это без сервера-посредника, поэтому я думаю, что это будет называться P2P

Я довольно неопытен с сетевыми решениями и только начал изучать, так что я мало что знаю об этом. Я хотел создать эту программу для образовательных целей, а также функциональность, которую она предоставляет.

Эта проблема

Теперь у меня есть теория, но нет практической части. Я не знаю, как получить этот публичный IP-адрес. Я провел некоторое исследование и выяснил, что винапи не может найти его локально. Я также узнал, что сервер, конечно, знает мой IP, когда я подключаюсь к нему, и поэтому я мог бы использовать службу в качестве этой проверки ip, но я действительно не хочу полагаться на неофициальные проекты, где я не знаю, разрешено ли мне использовать его в моем проекте и как долго они будут жить.

О чем я думал

Так что я задавался вопросом, есть ли сервисы, которые можно бесплатно использовать для этой цели, например, Google или что-то. Я также немного прочитал о DNS и подумал, могу ли я использовать Google DNS для этой цели. Моей последней попыткой было бы настроить небольшой сервер на бесплатной службе веб-хостинга и написать на нем небольшое приложение, к которому я мог бы подключиться и получить общедоступный IP-адрес, но, возможно, это было бы безуспешно.

Вопрос

Я пытаюсь задать четкий вопрос: я на правильном пути с одной из моих попыток решения или есть что-то, что я полностью упускаю?

Код

так как был запрос на MCVE, я попытался написать немного кода, чтобы показать, чего я хочу достичь и как я это сделаю, я надеюсь, что это ясно и понятно:

#include <iostream>
#include <winsock2.h>
#include <windows.h>


ULONG getPublicAddr() {
    /* This is what i came up with so far this is just non working code to show what i want */
    SOCKET i_ask_a_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    sockaddr_in addr_of_server_to_ask;
    addr_of_server_to_ask.sin_family = AF_INET;
    addr_of_server_to_ask.sin_port = htons(53); /* DNS port as i have read */
    addr_of_server_to_ask.sin_addr.s_addr = inet_addr("8.8.8.8"); /* This is where i think i need to put an ip of a server i can ask for my IP i read a bit around and think the google 
    DNS might be what i was looking for */
    connect(i_ask_a_server, (sockaddr *) &addr_of_server_to_ask, sizeof(sockaddr_in));
    /* Now send a request and receive the result or something... */

    closesocket(i_ask_a_server);
    return inet_addr("127.0.0.1"); /* <- the public IP i would receive. For now just with a dummy */
}


int main () {
    ULONG publicAddr = getPublicAddr();
    SOCKET server;
    server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    /* Check for valid socket here */
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(10000); /* Or whatever port */
    serverAddr.sin_addr.s_addr = publicAddr; /* <- here i would need to add the public address to create a connection over the Internet */
    bind(server, (sockaddr *) &serverAddr, sizeof(sockaddr_in)); /* Bind the server to the IP and port and listen for connections over the Internet */
    /* Also check for valid binding */

    listen(server, 1);
    sockaddr_in clientAddr;
    int clientAddrLen = sizeof(sockaddr_in);
    /* Maybe do some checking before blindly accept the connection */
    SOCKET client = accept(server, (sockaddr *) & clientAddr, &clientAddrLen);
    /* You know the procedure... */
    std::cout << "Connected to client: " << inet_ntoa(clientAddr.sin_addr) << std::endl; /* I thought of something like this for a little webserver that then sends this result back to the application because that would be the public IP as i understood */

    CHAR buffer[4096]; /* Just about enough for whatever purpose */
    int result;
    while (true) {
        result = recv(server, buffer, sizeof(buffer), 0); /* receive data */
        if (result <= 0) break; /* If no data could be received or connection was lost break. Maybe do error checking in before */
        std::cout << "Received " << result << " B" << std::endl;
    }

    closesocket(client);
    closesocket(server);

    return 0;
}

0 ответов

Другие вопросы по тегам