2010-01-14 109 views
16

我有一個服務器與來自客戶端的傳入套接字。 我需要獲取遠程客戶端的IP地址。 嘗試谷歌搜索in_addr,但它有點麻煩。 有什麼建議嗎?獲取傳入套接字連接的源地址

+0

組in_addr是IPv4的特定,反正 – bortzmeyer 2010-01-14 18:15:57

+0

man getpeername 2010-01-14 14:18:28

+0

看到在linux INET_NTOA(..)函數.. '男人INET_NTOA'。在我看來,它比inet_ntop更容易,並且需要包括arpa/inet.h。這裏是一個例子:http://www.binarytides.com/programming-udp-sockets-c-linux/ – mhk 2016-08-11 07:51:53

回答

32

您需要getpeername函數。偉大的Beej的網絡指南有一個page about it。下面是有一個代碼示例:

// assume s is a connected socket 

socklen_t len; 
struct sockaddr_storage addr; 
char ipstr[INET6_ADDRSTRLEN]; 
int port; 

len = sizeof addr; 
getpeername(s, (struct sockaddr*)&addr, &len); 

// deal with both IPv4 and IPv6: 
if (addr.ss_family == AF_INET) { 
    struct sockaddr_in *s = (struct sockaddr_in *)&addr; 
    port = ntohs(s->sin_port); 
    inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); 
} else { // AF_INET6 
    struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; 
    port = ntohs(s->sin6_port); 
    inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); 
} 

printf("Peer IP address: %s\n", ipstr); 
+0

+1。但是,我們不必爲此釋放任何內存? – iammilind 2014-07-27 17:19:55

+1

我注意到'struct sockaddr_in * s'在外部範圍中隱藏套接字's'。有一個陰影變量並不理想。 – 2015-06-22 23:12:53

+0

有沒有辦法從地址 – Bionix1441 2016-12-06 09:01:19

1

既然你說,這是來自客戶端的傳入連接,以替代getpeername你可以只保存由accept()調用返回的地址,在第二和第三參數。

9

假設您使用accept()接受傳入的套接字連接,則不需要getpeername()。地址信息可通過accept()呼叫的第二個和第三個參數獲得。

這裏是禮的回答修改,以做沒有getpeername()

int client_socket_fd; 
socklen_t len; 
struct sockaddr_storage addr; 
char ipstr[INET6_ADDRSTRLEN]; 
int port; 

len = sizeof addr; 
client_socket_fd = accept(server_socket_fd, (struct sockaddr*)&addr, &len); 

// deal with both IPv4 and IPv6: 
if (addr.ss_family == AF_INET) { 
    struct sockaddr_in *s = (struct sockaddr_in *)&addr; 
    port = ntohs(s->sin_port); 
    inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); 
} else { // AF_INET6 
    struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; 
    port = ntohs(s->sin6_port); 
    inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); 
} 

printf("Peer IP address: %s\n", ipstr); 
+0

+1得到socketDescriptor直接使用'accept()'。但是,我們不必爲此釋放任何內存? – iammilind 2014-07-27 17:19:09

+3

@iammilind:我不認爲任何內存需要被釋放 - 我看不到任何動態分配正在完成。這一切都是用靜態分配的變量完成的。 – 2014-07-31 00:42:22