我有这个代码在客户端关闭或丢失连接时获取客户端的IP。
char buffer[80];
ssize_t bread;
struct sockaddr_in peer;
socklen_t peer_len;
peer_len = sizeof(peer);
memset(&buffer, 0, sizeof(buffer));
bread = read(connectlist[listnum], buffer, 80);
if (bread < 0)
{
if(getpeername(connectlist[listnum],(struct sockaddr *) &peer, &peer_len) == -1){
perror("getpeername() failed");
}
printf("Connection Reset From IP: %s\n", inet_ntoa(peer.sin_addr));
_Print_To_File(inet_ntoa(peer.sin_addr));
close(connectlist[listnum]);
close(connectlist[listnum]);
connectlist[listnum] = 0;
}
if(bread == 0)
{
if(getpeername(connectlist[listnum],(struct sockaddr *) &peer, &peer_len) == -1){
perror("getpeername() failed");
}
printf("Connection Closed From IP: %s\n", inet_ntoa(peer.sin_addr));
_Print_To_File(inet_ntoa(peer.sin_addr));
close(connectlist[listnum]);
connectlist[listnum] = 0;
}
我可以在连接关闭时获取客户端的IP但在连接重置时我没有得到客户端的IP。连接重置时得到0.0.0.0。我怎样才能解决这个问题。感谢,
答案 0 :(得分:2)
getpeername()
仅适用于已连接的套接字。套接字断开连接后,调用时会出现ENOTCONN
错误。这就是getpeername()
有时用于检查套接字是否已连接的原因。
答案 1 :(得分:1)
您可能希望使用struct sockaddr
之前调用accept()
所返回的read()
。
从man accept
逐字逐句
int accept(int sockfd,struct sockaddr * addr,socklen_t * addrlen);
[...]
参数addr是一个指向sockaddr结构的指针。 此 如已知的那样,结构用对等套接字的地址填充 到通信层。返回的地址的确切格式 addr是由 套接字的地址族(请参阅socket(2)和各自的协议手册页)。当addr为NULL时,不会填充任何内容;在这 case,addrlen不使用,也应该是NULL。