虽然这些是很好的答案,但他们用-pedantic -std=c99 -Werror 破坏了我的编译。
来自man 7 socket
为了允许将任何类型的套接字地址传递给套接字 API 中的接口,定义了 struct sockaddr 类型。的目的
这种类型纯粹是为了允许转换特定于域的套接字地址
类型为“通用”类型,以避免编译器关于类型的警告
对套接字 API 的调用不匹配。
从glibc-2.17 (RHEL7) 中获取此页面中的所有相关数据,我看到了
/* Structure describing a generic socket address. */
struct sockaddr
{
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
char sa_data[14]; /* Address data. */
};
其中 SOCKADDR_COMMON 是 uint16_t。所以总大小是16B。
IP(互联网协议)域特定,来自 man 7 ip:
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
第一次尝试
inet_ntoa( ((struct sockaddr_in) peer_addr).sin_addr )
问题
error: conversion to non-scalar type requested
第二次尝试
inet_ntoa( ((struct sockaddr_in *) &peer_addr)->sin_addr ) ));
问题
error: dereferencing type-punned pointer might break strict-aliasing rules [-Werror=strict-aliasing]
第三次尝试:inet_pton,无论如何更现代,线程安全,占用 void*
char peer_addr_str[ INET_ADDRSTRLEN ];
inet_ntop( AF_INET, &peer_addr, peer_addr_str, INET_ADDRSTRLEN );
好的,工作。人类可读的十进制和点字符串位于peer_addr_str。