coming
天行健 君子以自强不息
记录我的成长
通用socket地址
表示socket地址的结构体sockaddr。
1 2 3 4 5 6 7 8 9
|
struct sockaddr{ sa_family_t sa_family; char sa_data[14]; };
|
14字节的sa_data无法容纳所有协议族的地址值;因此,Linux定义了如下新的通用socket地址结构体sockaddr_storage。
1 2 3 4 5 6 7 8
|
struct sockaddr_storage{ sa_family_t ss_family; char __ss_padding[(128 - (sizeof (unsigned short int)) - sizeof (unsigned long int))]; unsigned long int __ss_align; };
|
专用socket地址
上述通用socket结构体不易操作,Linux专门提供如下专用socket地址结构体。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
struct sockaddr_un{ sa_family_t sun_family; char sun_path[108]; };
struct sockaddr_in{ sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; unsigned char sin_zero[sizeof (struct sockaddr) - (sizeof (unsigned short int)) - sizeof (in_port_t) - sizeof (struct in_addr)]; };
struct in_addr{ in_addr_t s_addr; };
struct sockaddr_in6{ sa_family_t sin6_family; in_port_t sin6_port; uint32_t sin6_flowinfo; struct in6_addr sin6_addr; uint32_t sin6_scope_id; };
struct in6_addr{ union{ uint8_t __u6_addr8[16]; uint16_t __u6_addr16[8]; uint32_t __u6_addr32[4]; } __in6_u; };
|
所有专用socket地址类型的变量在实际使用时都需要转化为通用socket地址类型sockaddr。
IP地址转换
点分十进制字符串转结构体in_addr。
1 2 3 4 5 6
|
int inet_aton(const char * cp, struct in_addr * inp);
|
结构体in_addr转点分十进制字符串。
1 2 3 4
|
char * inet_ntoa(struct in_addr in);
|
上述两个函数不可重入
还有同时适用于IPv4与IPv6地址转换的一对函数。
点分十进制字符串(IPv4地址)或冒号分16进制字符串(IPv6)转对应结构体,即结构体in_addr或结构体in6_addr;由__af
参数指定协议族,一般取宏AF_INET或AF_INET6。
1 2 3 4 5 6
|
int inet_pton (int __af, const char * cp, void * buf);
|
结构体in_addr或结构体in6_addr转换为对应的字符串表示。
1 2 3 4 5 6 7 8
|
const char * inet_ntop (int af, const void * cp, char * buf, socklen_t len);
|
本文代表个人观点,内容仅供参考。若有不恰当之处,望不吝赐教!