2011-09-07 64 views
7

我有一個sockaddr_storage包含遠程主機的ipv4地址和端口。我之前沒有看到這些struct s,但我不知道如何將它轉換爲可以直接檢索IP地址和端口號的struct。我試過Google搜索struct,但沒有找到任何東西。有關如何做到這一點的任何建議?從sockaddr_storage檢索ip和端口

感謝

+0

你確定它是'sockaddr_storage'結構而不是'sockaddr'結構嗎? –

+0

是的,這是一個sockaddr_storage結構。 – KaiserJohaan

+1

@Tony:'sockaddr_storage'是較新代碼中使用的首選結構,因爲它支持多種地址系列,包括IPv4和IPv6。 –

回答

5

,就可以把指針struct sockaddr_in *struct sockaddr_in6 *和直接訪問成員,但是這要忌諱的,可混疊違規和miscompilation問題。

一個更好的方法是將指針傳遞給getnameinfo,使用NI_NUMERICHOSTNI_NUMERICSERV標誌來獲取地址和端口的字符串表示形式。這具有無需附加代碼即可支持IPv4和IPv6的優點,理論上也支持所有未來的地址類型。您可能必須將指針投射到void *(或明確指定struct sockaddr *,如果您使用的是C++)才能將它傳遞到getnameinfo,但這不會導致問題。

+0

我只使用C標準庫;從字符串中提取端口聽起來很痛苦。如果我事先知道它是Ipv4還是Ipv6,那麼把它轉換成sockaddr_in/sockaddr_in6結構體沒有問題嗎? – KaiserJohaan

+0

我不明白'atoi'是多麼的難... –

2

爲了擴展一個答案上述和提供一種使用getnameinfo功能的代碼,檢查此片段:

struct sockaddr_storage client_addr; 
socklen_t client_len = sizeof(struct sockaddr_storage); 

// Accept client request 
int client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len); 

char hoststr[NI_MAXHOST]; 
char portstr[NI_MAXSERV]; 

int rc = getnameinfo((struct sockaddr *)&client_addr, client_len, hoststr, sizeof(hoststr), portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV); 
if (rc == 0) printf("New connection from %s %s", hoststr, portstr); 

結果是一個hoststr包含來自struct sockaddr_storage一個IP地址和一個portstr分別包含一個端口。