Linux 套接字的结构定义

Linux 在头文件 sys/socket.h 中定义了一种通用的套接字结构类型,以供不同的协议进行调用。

struct sockaddr
{
    unsigned short int sa_family;//套接字协议地址类型
    unsigned char sa_data[14];//14字节的协议地址,包括IP地址和端口
};
  • sa family:套接字的协议族地址类型。
  • sa_data:具体的协议地址,不同的协议族对应不同的地址结构。

常见协议对应的 sa_family 值

可选值 说明
AF_INET IPv4协议
AF_INET6 IPv6协议
AF_LOCAL UNIX协议
AF_LINK 链路地址协议
AF_KEY 密钥套接字

除了 sockaddr 之外,Linux 还在 netinet/in.h 中定义了另外一种结构类型 sockaddr_in,其和 sockaddr 等效且可以互相转换,通常会在涉及 TCP/IP 的协议编程中使用。

struct sockaddr_in
{
    int sa_len;//长度单位
    short int sa_family;//地址族
    unsigned short int sin_port;//端口号
    struct in_addr sin_addr;//IP地址
    unsigned char sin_zero[8];//填充0以保持与struct sockaddr同样大小
};
  • sa_len:长度单位,不必设置,通常情况下固定长度为16字节。
  • sa_family:协议族。
  • sin_port:端口号。
  • sin_addr:IP地址, 其本身也是一个结构体,对该结构体的描述说明如下。
struct sin_addr
{
    in addr_t s_add; //32位IPv4地址,网络字节顺序
};
  • sin_zero:填充0,目的是为了保持该结构和 sockaddr 结构同样的大小,以方便转换。

使用结构 sockaddr _in 时需注意以下几点:

  • 结构 sockadd_in 中的 TCP 或 UDP 端口号 sin_port 和 IP 地址 sin_addr 都是以网络字节顺序存储的。
  • 32位的 IP 地址可以利用两种不同的方法引用,例如,假设定义变量 sevaddr 为Internet 套接字的地址结构,那么可以用 servaddr.sin_addr 或 servaddr.sin_addr.s_addr 来引用这个 IP 地址,需要注意的是前一种引用是结构类型(struct sin_addr)的数据,而后一种引用是整数类型的数据;当将 IP 地址作为函数参数使用时,需要明确使用哪种类型的数据,因为编译器对结构类型参数和整数类型参数的处理方式不一样。
  • sin_zero 成员未被使用,它是为了和通用套接字地址(struct sockaddr)保持一致而引入的,通常会被填充为 0。
  • 套接字地址结构仅供本机 TCP 协议记录套接字信息而用,这个结构变量本身是不在网络上传输的,但是其某些内容,如 IP 地址和端口号是在网络上传输的,因此这两部分数据需要转换成网络字节顺序。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章