2011-09-07 69 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分别包含一个端口。