如何从sockaddr获取IP地址

adh*_*lon 24 c++ sockets ip-address

我想在调用accept之后尝试获取客户端的ip地址.这是我到目前为止所拥有的,但我最终得到一些显然不是IP地址的长号码.可能有什么不对?

int tcp_sock = socket(AF_INET, SOCK_STREAM, 0);

sockaddr_in client;
client.sin_family = AF_INET;
socklen_t c_len = sizeof(client);

int acc_tcp_sock = accept(tcp_sock, (sockaddr*)&client, &c_len);
cout << "Connected to: " << client.sin_addr.s_addr << endl;
Run Code Online (Sandbox Code Playgroud)

ofa*_*vre 30

http://beej.us/guide/bgnet/examples/client.c看:

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET)
        return &(((struct sockaddr_in*)sa)->sin_addr);
    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

// [...]

struct addrinfo *p;
char s[INET6_ADDRSTRLEN];
inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s);
Run Code Online (Sandbox Code Playgroud)

它使用inet_ntop,优先于inet_ntoa(非线程安全),因为它处理IPv4和IPv6(AF_INETAF_INET6),我认为应该是线程安全的.


Jam*_*lis 28

这个长数字整数形式的IP地址(毕竟IP地址只是一个整数;当我们将八位字节分开并将其放入点表示法时,人们更容易使用它).

您可以使用inet_ntoa将整数值转换为标准点表示法.

  • 请注意,现在`inet_ntoa`被视为已弃用.你应该使用支持更多格式的`inet_ntop`. (3认同)

Alo*_*lon 6

你得到的是IP地址的原始32位整数表示.要获得熟悉的点分隔字符串,请使用以下函数:

 char * inet_ntoa(struct in_addr addr);
Run Code Online (Sandbox Code Playgroud)

这会将整数转换为静态字符串.