UNIX 网络编程 卷1:套接字联网API
套接字编程简介
1 套接字地址结构
-
对于一个套接字描述符,需要将它绑定到具体的套接字上,而不同协议的套接字具有不同的结构,它们都以
sockaddr_
开头,并附加一个后缀用来表示具体的套接字类型。 -
IPv4的套接字结构
-
IPv4套接字定义在
<netinet/in.h>
头文件中,显然对应的套接字名称为sockaddr_in
。注:
in
是Internet的缩写,而结构中的sin_
即为sockaddr_in
的缩写。
struct in_addr{ in_addr_t s_addr; // 32-bit IPv4 address // network byte ordered }; struct sockaddr_in{ uint8_t sin_len; // length of structure (16) sa_family_t sin_family; // AF_INET in_port_t sin_port; // 16-bit TCP or UPD port number in_addr sin_addr; // 32-bit IPv4 address char sin_zero[8]; // unused };
- 在套接字中的长度选项并不需要设置和检查,只是为了实现可变长套接字结构的通用实现。
- 在这个套接字中有三个重要字段:
family
、port
、addr
,而zero
字段只是为了填充大小 - IPv4的地址和端口号在套接字中总是以网络字节序来存储。
- 32位IPv4地址可以描述为一个
in_addr
结构或其中的in_addr_t
类型,故将IPv4地址作为参数时存在两种不同的类型,需要正确处理。 - 在使用
sockaddr_
结构前,一般需要将整个结构置零,随后只填写需要使用的字段,其余字段不需要特别处理。 - 套接字结构不具有可移植性,仅支持在特定主机上使用。
-
-
通用套接字结构
struct sockaddr{ uint8_t sa_len; // sa as a shorthand of sockaddr sa_fimily_t sa_family; // address family: AF_xxx value char sa_data[14]; // protocol-specific address }
bind
函数的接口使用的是sockaddr
,而套接字没有实现继承体系,所以在使用特定协议套接字时,需要进行强制类型转换,例如:static_cast< sockaddr* > ( &sockaddr_in_server )
。
-
IPv6套接字
- IPv6套接字定义在
<netinet/in.h>
头文件中,对应套接字名为sockaddr_in6
,不难推测,套接字中的字段均以sin6
开头。
struct in6_addr{ uint8_t s6_addr[16]; // 128-bit IPv6 address }; #define SIN6_LEN // required for compile-time tests struct sockaddr_in6{ uint8_t sin6_len; // length of this struct (28) sa_family_t sin6_family; // AF_IN
- IPv6套接字定义在