第一个套接字连接来自远程IP是0.0.0.0,所有后续连接都没问题

时间:2017-11-20 08:56:04

标签: c++ sockets

我有一个程序正在侦听下面定义的套接字。我看到的问题是,在第一个连接上,客户端地址值为" 0.0.0.0"。

客户端不在本地计算机上,而是从远程IP连接。除了错误的IP之外,连接似乎很好。

所有后续连接都具有连接客户端的实际远程IP地址,例如" 8.8.8.8"。

为什么第一个连接会将地址报告为" 0.0.0.0"?

void client_loop(int client_socket, const string& client_address) {
    LOG4CXX_INFO(logger, "client_loop(" << client_address << ")");

    while(active) {
        boost::this_thread::sleep(seconds(1));
    }
}

void server_loop(unsigned short server_port) {
    LOG4CXX_INFO(logger, "server_loop(" << server_port << ")");

    int server_socket = socket(AF_INET, SOCK_STREAM, 0);

    if (server_socket < 0) {
        LOG4CXX_ERROR(logger, "socket() - " << strerror(errno));
        return;
    }

    in_addr_t s_addr = htonl(INADDR_ANY);

    struct sockaddr_in server_sockaddress;
    struct sockaddr_in client_sockaddress;
    unsigned int client_length(0);

    memset((char *) &server_sockaddress, 0, sizeof(server_sockaddress));
    memset((char *) &client_sockaddress, 0, sizeof(client_sockaddress));

    server_sockaddress.sin_family = AF_INET;
    server_sockaddress.sin_addr.s_addr = s_addr;
    server_sockaddress.sin_port = htons(server_port);

    bind(server_socket, (struct sockaddr*) &server_sockaddress, sizeof(server_sockaddress));

    listen(server_socket, 10);

    int client_socket(0);

    LOG4CXX_INFO(logger, "Listening on Port " << port);

    while(active) {
        client_socket = accept(server_socket, (struct sockaddr *) &client_sockaddress, &client_length);

        if(client_socket > 0) {
            string client_address(inet_ntoa(client_sockaddress.sin_addr));

            new boost::thread(boost::bind(client_loop, client_socket, client_address));
        } else {
            LOG4CXX_ERROR(logger, "accept() - " << strerror(errno));
        }

        memset((char *) &client_sockaddress, 0, sizeof(client_sockaddress));
    }
}

1 个答案:

答案 0 :(得分:2)

您的问题是,您未将client_length初始化为sizeof(client_sockaddr),而是将其保留为第1次运行的0。

来自accept documentation

  

如果提供的缓冲区也是截断的,则返回的地址将被截断   小;在这种情况下,addrlen将返回一个大于was的值   提供给电话。

这意味着在第一次运行时,系统不会将任何数据填入您的sockaddr结构中,该结构已初始化为0 - 因此您获得的结果为0.0.0.0

下一次运行将使用先前系统调用返回的大小,该大小修复了后续运行中的问题(存在缓冲区溢出的风险,请注意)。