socket网络编程之常用地址API

通用socket地址

  socket网络编程接口中表示socket地址的是结构体sockaddr,定义:
socket网络编程之常用地址API_第1张图片
  sa_family成员是地址族类型(sa_family_t)的变量。地址族类型通常与协议族类型对应。常见的协议族(protocol family,也称domain)和对应的地址族如下:
在这里插入图片描述
  宏PF_*和AF_*都定义在bits/socket.h头文件中,且后者与前者有完全相同的值,所以二者经常混用。
  在这里插入图片描述
  sa_data成员用于存放socket地址值。不同的协议族的地址值具有不同的含义和长度。
socket网络编程之常用地址API_第2张图片
  14字节的sa_data根本无法容纳多数协议族的地址值。Linux定义了下面这个新的通用的socket地址结构体:
socket网络编程之常用地址API_第3张图片
  这个结构体不仅够大还是内存对齐的(__ss_align成员的作用)。

专用socket地址

  通用的socket地址结构体显然很不好用,比如设置或获取IP地址和端口号就需要执行繁琐的位操作。所以Linux为各个协议族提供了专门的socket地址结构体。
  UNIX本地域协议族使用如下专用socket地址结构体:
socket网络编程之常用地址API_第4张图片
  TCP/IP协议族有sockaddr_in和sockaddr_in6两个专用socket地址结构体,他们分别用于IPv4和IPv6:
socket网络编程之常用地址API_第5张图片
注意:所有专用socket地址(以及sockaddr_storage)类型的变量在实际使用时都需要转化为通用socket地址类型sockaddr(强转),因为所有socket编程接口使用的地址参数的类型都是sockaddr。

IP地址转换函数

  通常,我们使用可读性好的点分十进制字符串表示IPv4地址,以及用十六进制字符串表示IPv6地址。但编程中需要先把他们转换为二进制方能使用。
  下面三个函数可用于点分十进制字符串表示的IPv4地址和用网络字节序整数表示的IPv4地址之间的转换:
socket网络编程之常用地址API_第6张图片
  inet_ntoa函数将网络字节序整数表示IPv4地址转化为用点分十进制字符串表示的IPv4地址。但是,该函数内部使用一个静态变量存储转化结果,函数的返回值指向该静态内存,因此inet_ntoa是不可重入的。
socket网络编程之常用地址API_第7张图片
INET_ADDRSTRLEN

  这是32位ipv4地址,用10进制+句点表示时,所使用内存长度的最大值。
  111.111.111.111 这是最大长度的一个例子,其中包括4组十进制整数,每组3个,三个句点,再加一个NULL符号,所以总共需要4*3+3+1=16个字节

INET6_ADDRSTRLEN

  这是128位ipv6地址,用十六进制+冒号显示时,所使用内存长度的最大值。也支持兼容ipv4的兼容格式
  非兼容格式:1111:1111:1111:1111:1111:1111:1111:1111,这是非兼容格式最大长度的一个例子,其中包括8组十六进制整数,每组4个,七个冒号,再加一个NULL结束符,所以总共需要8x4+7+1=40个字节。
  兼容格式:1111:1111:1111:1111:1111:1111:111.111.111.111,这是兼容格式最大长度的一个例子,其中包括6组十六进制整数,每组4个,六个冒号,再加一组ipv4地址,一个NULL结束符,所以总共需要6x4+6+16=46个字节

你可能感兴趣的:(Linux网络编程)