从sockaddr结构获取IPV4地址
我怎样才能提取到一个string的IP地址? 我找不到一个引用,告诉我如何编码char sa_data[14]
。
一旦sockaddr
投射到sockaddr_in
,它变成这样:
struct sockaddr_in { u_short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; };
只需将整个sockaddr
结构投射到sockaddr_in即可 。 那么你可以使用:
char *ip = inet_ntoa(their_addr.sin_addr)
检索标准的ip表示。
Emil的答案是正确的,但是我的理解是inet_ntoa
已被弃用,而应该使用inet_ntop
。 如果您使用的是IPv4,请将您的struct sockaddr
为sockaddr_in
。 你的代码看起来像这样:
struct addrinfo *res; // populated elsewhere in your code struct sockaddr_in *ipv4 = (struct sockaddr_in *)res->ai_addr; char ipAddress[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(ipv4->sin_addr), ipAddress, INET_ADDRSTRLEN); printf("The IP address is: %s\n", ipAddress);
看看这个伟大的资源 ,更多的解释,包括如何做到这一点的IPv6地址。
inet_ntoa()
适用于IPv4; inet_ntop()
适用于IPv4和IPv6。
给定一个inputstruct sockaddr *res
,这里有两个代码片段:
使用inet_ntoa()
struct sockaddr_in *addr_in = (struct sockaddr_in *)res; char *s = inet_ntoa(addr_in->sin_addr); printf("IP address: %s\n", s);
使用inet_ntop()
char *s = NULL; switch(res->sa_family) { case AF_INET: { struct sockaddr_in *addr_in = (struct sockaddr_in *)res; s = malloc(INET_ADDRSTRLEN); inet_ntop(AF_INET, &(addr_in->sin_addr), s, INET_ADDRSTRLEN); break; } case AF_INET6: { struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)res; s = malloc(INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &(addr_in6->sin6_addr), s, INET6_ADDRSTRLEN); break; } default: break; } printf("IP address: %s\n", s); free(s);
您可以使用Windows和Linux的 getnameinfo
。
假设你有一个好的(即它的成员有合适的值) sockaddr*
称为pSockaddr
:
char clienthost[NI_MAXHOST]; //The clienthost will hold the IP address. char clientservice[NI_MAXSERV]; int theErrorCode = getnameinfo(pSockaddr, sizeof(*pSockaddr), clienthost, sizeof(clienthost), clientservice, sizeof(clientservice), NI_NUMERICHOST|NI_NUMERICSERV); if( theErrorCode != 0 ) { //There was an error. cout << gai_strerror(e1) << endl; }else{ //Print the info. cout << "The ip address is = " << clienthost << endl; cout << "The clientservice = " << clientservice << endl; }