我有一个sockaddr_storage
包含远程主机的ipv4地址和端口。我之前没有看到这些struct
s,但我不知道如何将它转换为可以直接检索IP地址和端口号的struct
。我试过Google搜索struct
,但没有找到任何东西。有关如何做到这一点的任何建议?从sockaddr_storage检索ip和端口
感谢
我有一个sockaddr_storage
包含远程主机的ipv4地址和端口。我之前没有看到这些struct
s,但我不知道如何将它转换为可以直接检索IP地址和端口号的struct
。我试过Google搜索struct
,但没有找到任何东西。有关如何做到这一点的任何建议?从sockaddr_storage检索ip和端口
感谢
,就可以把指针struct sockaddr_in *
或struct sockaddr_in6 *
和直接访问成员,但是这要忌讳的,可混叠违规和miscompilation问题。
一个更好的方法是将指针传递给getnameinfo
,使用NI_NUMERICHOST
和NI_NUMERICSERV
标志来获取地址和端口的字符串表示形式。这具有无需附加代码即可支持IPv4和IPv6的优点,理论上也支持所有未来的地址类型。您可能必须将指针投射到void *
(或明确指定struct sockaddr *
,如果您使用的是C++)才能将它传递到getnameinfo
,但这不会导致问题。
我只使用C标准库;从字符串中提取端口听起来很痛苦。如果我事先知道它是Ipv4还是Ipv6,那么把它转换成sockaddr_in/sockaddr_in6结构体没有问题吗? – KaiserJohaan
我不明白'atoi'是多么的难... –
为了扩展一个答案上述和提供一种使用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
分别包含一个端口。
你确定它是'sockaddr_storage'结构而不是'sockaddr'结构吗? –
是的,这是一个sockaddr_storage结构。 – KaiserJohaan
@Tony:'sockaddr_storage'是较新代码中使用的首选结构,因为它支持多种地址系列,包括IPv4和IPv6。 –