我有一个程序正在侦听下面定义的套接字。我看到的问题是,在第一个连接上,客户端地址值为" 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));
}
}
答案 0 :(得分:2)
您的问题是,您未将client_length
初始化为sizeof(client_sockaddr)
,而是将其保留为第1次运行的0。
来自accept
documentation:
如果提供的缓冲区也是截断的,则返回的地址将被截断 小;在这种情况下,addrlen将返回一个大于was的值 提供给电话。
这意味着在第一次运行时,系统不会将任何数据填入您的sockaddr
结构中,该结构已初始化为0 - 因此您获得的结果为0.0.0.0
下一次运行将使用先前系统调用返回的大小,该大小修复了后续运行中的问题(存在缓冲区溢出的风险,请注意)。