2011-10-28 162 views
0

我想知道如何讓誰連接到插座中使用接受服務器上的客戶端的IP地址。我將如何做到這一點? getpeername返回一個錯誤的IP地址,我似乎無法找到另一種方式來做到這一點。如何找到一個套接字的IP地址C++/C

在服務器上,之後接受退貨,我這樣做:

  char buf[INET_ADDRSTRLEN]; 
      struct sockaddr name; socklen_t len = sizeof(name); 
      getpeername(sock_fd, &name, &len); //sock_fd is the socket im using 
      inet_ntop(AF_INET, &name, buf, INET_ADDRSTRLEN); 
      string ip = buf; 
+0

請告訴我們你的一些代碼。 – ukhardy

+0

buf不是字符串 – nhed

回答

5

接受的第二個參數有這個信息。

+0

+100。對於任何尋找最簡單方法的人,如果您有權訪問接受呼叫,請使用該參數。我的getpeername真的很古怪,但這個解決方案運行得更好。 – akroy

1

胡亂猜測,基於有限的信息目前可用:確保你接受的連接上調用getpeername(),而不是在監聽套接字。

getpeername()返回時,它寫入的內容可能是in_addr_t(或in6_addr!)結構。使用像inet_ntoa這樣的程序來格式化並顯示結果。

2

你有幾個誤區:

  • 你不應該創建struct sockaddr類型的對象。相反,你應該使用struct sockaddr_instruct sockaddr_in6取決於插座的類型;
  • 您應該檢查的getpeername()錯誤的返回值。
  • 您必須將指向struct in_addrstruct in6_addr的指針傳遞給inet_ntop(),而不是指向sockaddr的指針。

它應該看起來像:

char buf[INET_ADDRSTRLEN] = ""; 
struct sockaddr_in name; 
socklen_t len = sizeof(name); 

if (getpeername(sock_fd, (struct sockaddr *)&name, &len) != 0) { 
    perror("getpeername"); 
} else { 
    inet_ntop(AF_INET, &name.sin_addr, buf, sizeof buf); 
} 

你並不需要使用getpeername(),雖然 - 你能傳遞(struct sockaddr *)&name&lenaccept()第二和第三個參數,並從那裏繼續。

相關問題