从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 sockaddrsockaddr_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; }