检索重置连接的客户端的IP地址

时间:2012-11-07 16:49:00

标签: c linux sockets

我有这个代码在客户端关闭或丢失连接时获取客户端的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。我怎样才能解决这个问题。感谢,

2 个答案:

答案 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。