WinSock c ++ inet_ntop всегда отображает 204.204.204.204 (и accept () не удалось) - PullRequest
0 голосов
/ 09 июля 2019

Я пытаюсь создать сервер winsock и хочу отображать IP-адрес клиента на сервере, когда он подключается, но именно в этом и заключается проблема. Каждый раз, когда я пытаюсь подключить его дисплей 204.204.204.204. Я пытался подключиться к другому компьютеру, но результат был тот же. результат в localhost

После этого я начал искать людей, имеющих ту же проблему, что и я, на этом веб-сайте, и я нашел несколько людей, у которых было то же самое, что и у меня, но у них у всех была либо функция accept, либо функция inet_ntop, которая работала некорректно. Поэтому я проверяю, и ни одна из этих двух функций не возвращает ошибку. Может быть, я глуп, но я действительно не могу понять, в чем проблема. (кстати, английский не мой родной язык, поэтому, пожалуйста, скажите мне, если вы заметили или мой английский не так уж плох)

часть кода, которая не работает

sockaddr_in from;
    int clientlen = sizeof(from);
    // accept
    SOCKET client = accept(server, (SOCKADDR*)&client, &clientlen);
    if (client == INVALID_SOCKET)
    {
        std::cout << "Error in accept(): " << WSAGetLastError << std::endl;
        WSACleanup();
    }
    else
    {

        char clientIp[17];
        if (inet_ntop(AF_INET, &from.sin_addr, clientIp, 17) == NULL)
        {
            std::cout << "Can't get the client's ip: " << WSAGetLastError() << std::endl;
        }

        std::cout << "ip connected: " << clientIp << std::endl;

весь код, если он вам нужен

#include <iostream>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <string>

#pragma comment(lib, "ws2_32.lib")

int main()
{
    std::cout << "--- Tcp/ip Server ---" << std::endl;
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);

    SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
    if (server == INVALID_SOCKET)
    {
        std::cout << "error in SOCKET(): "<< WSAGetLastError() << std::endl;
        WSACleanup();
    }
    sockaddr_in s;
    s.sin_family = AF_INET;
    s.sin_addr.s_addr = INADDR_ANY;
    s.sin_port = htons(52000);

    // bind
    if (bind(server, (sockaddr*)&s, sizeof(s)) == SOCKET_ERROR)
    {
        std::cout << "Error: bind()" << std::endl;
    }
    //listen
    if (listen(server, SOMAXCONN) == SOCKET_ERROR)
    {
        std::cout << "Error in listen(): " << WSAGetLastError() << std::endl;
        WSACleanup();
    }
    sockaddr_in from;
    int clientlen = sizeof(from);
    // accept
    SOCKET client = accept(server, (SOCKADDR*)&client, &clientlen);
    if (client == INVALID_SOCKET)
    {
        std::cout << "Error in accept(): " << WSAGetLastError << std::endl;
        WSACleanup();
    }
    else
    {

        char clientIp[17];
        if (inet_ntop(AF_INET, &from.sin_addr, clientIp, 17) == NULL)
        {
            std::cout << "Can't get the client's ip: " << WSAGetLastError() << std::endl;
        }

        std::cout << "ip connected: " << clientIp << std::endl;

        // the code isn't finished yet

        system("pause");
        WSACleanup();
    }
    return 0;
}

1 Ответ

1 голос
/ 09 июля 2019

Вы передаете адрес неправильной переменной во втором параметре accept().

Вы передаете адрес переменной SOCKET client, которой вы собираетесь присвоить результат accept(). C ++ позволяет использовать адрес переменной при объявлении и инициализации переменной в том же операторе. Но это не то, что вы хотите в этом случае. Вам нужно вместо этого передать адрес вашей переменной sockaddr_in from:

sockaddr_in from;
int clientlen = sizeof(from);
// accept
SOCKET client = accept(server, (SOCKADDR*)&from, &clientlen); // <-- &from instead of &client

Вы оставляете переменную from неинициализированной, и ваш компилятор заполняет неинициализированные переменные байтами 0xCC (десятичное 204) в режиме отладки, поэтому вы в конечном итоге видите 204.204.204.204 (hex 0xCC 0xCC 0xCC 0xCC) из inet_ntop() когда вы неправильно инициализируете переменную from.

...