2012-11-07 114 views
0

我有這個代碼,當客戶端關閉或失去連接時獲取客戶端的IP。檢索獲得連接重置客戶端的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

'accept()'完成beforhand,會給你的客戶端地址和端口。 – alk

+0

因此,在accept上使用struct sockaddr會給我客戶端的ip地址?..謝謝。 – demic0de

+0

你需要檢查'errno',然後盲目地假設你有重置。這可能是其他幾件事。爲什麼你關閉了兩次插座? – EJP

回答

1

您可能會喜歡使用在之前完成調用返回的struct sockaddraccept()

逐字從man accept

INT接受(INT的sockfd,結構sockaddr *地址中,socklen_t * addrlen中);

[...]

的參數addr是一個指向sockaddr結構體。 這個 結構用對等套接字的地址填充,如已知的 給通信層。返回地址的確切格式 addr由套接字的地址系列(請參閱套接字(2)和各自的協議手冊頁)確定。當addr爲NULL時,不填充任何內容;在這個 的情況下,addrlen不被使用,並且也應該是NULL。

+0

好的,謝謝你會嘗試一個。 – demic0de

+0

但是有什麼區別?我的連接關閉ip但沒有連接重置? – demic0de

+0

如果連接已經復位等信息已經消失了。 @ demic0de – alk

2

getpeername()僅適用於連接的插座。一旦套接字斷開連接,您將在調用它時收到ENOTCONN錯誤。這就是爲什麼getpeername()有時用作檢查插座是否已連接。