WinSock c ++ inet_ntop始终显示204.204.204.204(并且accept()并未失败)

时间:2019-07-09 02:36:33

标签: c++ c networking winsock winsock2

我正在尝试制作Winsock服务器,并且我想在客户端连接时在服务器上显示客户端的ip,但这就是问题所在。每次尝试连接时,都会显示204.204.204.204。我尝试连接另一台计算机,但结果相同。 result in 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 个答案:

答案 0 :(得分:1)

您在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(如果您未正确初始化0xCC 0xCC 0xCC 0xCC变量,则从inet_ntop()十六进制from)。