虽然这些答案很好,但在使用-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(Internet Protocol)是领域特定的,来自man 7 ip:
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
};
struct in_addr {
uint32_t s_addr;
};
首次尝试
inet_ntoa( ((struct sockaddr_in) peer_addr).sin_addr )
问题
error: conversion to non-scalar type requested
Second try
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
中。
inet_ntoa
被认为是过时的。您应该使用支持更多格式的inet_ntop
。 - Alexis Wilke