从sockaddr结构获取IPV4地址

Fel*_*zar 48 c ip-address

如何将IP地址提取到字符串中?我找不到一个参考,告诉我如何char sa_data[14]编码.

Emi*_*l H 58

只需将整个sockaddr结构转换为sockaddr_in即可.然后你可以使用:

char *ip = inet_ntoa(their_addr.sin_addr)
Run Code Online (Sandbox Code Playgroud)

检索标准ip表示.

  • +1.根据平台,请记得先检查一下家人.可能没有要提取的IPV4地址...... (14认同)
  • `if(their_sockaddr_ptr-> sa_family == AF_INET){struct sockaddr_in*their_inaddr_ptr =(struct sockaddr_in*)their_sockaddr_ptr; } else {/*不是IPv4地址*/}`或类似的. (6认同)

jrc*_*jrc 31

inet_ntoa()适用于IPv4; inet_ntop()适用于IPv4和IPv6.

给定输入struct 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);
Run Code Online (Sandbox Code Playgroud)

使用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);
Run Code Online (Sandbox Code Playgroud)


Joh*_*ohn 28

埃米尔的答案是正确的,但我的理解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);
Run Code Online (Sandbox Code Playgroud)

请查看这个优秀的资源以获得更多解释,包括如何为IPv6地址执行此操作.


Amb*_*ber 24

一旦sockaddr投出sockaddr_in,它就变成了:

struct sockaddr_in {
    u_short     sin_family;
    u_short     sin_port;
    struct      in_addr sin_addr;
    char        sin_zero[8];
};
Run Code Online (Sandbox Code Playgroud)


use*_*622 5

您可以用于getnameinfo WindowsLinux

假设你有一个好的(即它的成员有适当的值)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;
}
Run Code Online (Sandbox Code Playgroud)