地址结构 | 说明 |
---|---|
sockaddr_un | UNIX通信域套接字地址 |
sockaddr_in | IPv4套接字地址 |
sockaddr | 操作系统使用的套接字地址 |
sockaddr_in6 | IPv6套接字地址 |
struct sockaddr_un
{
sa_familly_t sun_family;
char sun_path[];
}
/* 在头文件<netinet/in.h>中定义 */
struct in_addr
{
in_addr_t s_addr;
};
struct sockaddr_in
{
uint8_t sin_len; /* POSIX不要求这个字段,它是OSI协议中新增的 */
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8]; /* 未使用 */
};
套接字地址结构的每个成员都是以**sin_**开头的。表示的就是socket internet。
- sin_family地址族字段:IPv4为AF_INET
- sin_zero这个字段一般置为0。
数据类型 | 头文件 | 说明 |
---|---|---|
sa_family_t | <sys/socket.h> |
|
socklen_t | <sys/socket.h> |
uint32_t |
in_addr_t | <netinet/in.h> |
IPV4地址uin32_t |
in_port_t | <netinet/int.h> |
端口uint16_t |
由于历史原因,地址类型(in_addr)定义成了矢量(即结构体),实际上因为其只包含一个字段,完全可以用标量来表示。
节选自《UNP》的解释
早期版本(4.2BSD)把in_addr定义为多种结构的联合,允许访问一个32为IPv4地址的所有4个字节,或者2个16位值。在IP地址划分为A、B、C类的时期,便于获取地址中的适当字节(比如单独获取网络号或主机号)。然后随着子网划分技术的来临和五分类编址(CIDR)的出现,各种地址类正在消失。那个联合已经不再需要了。 不难理解,IPv4的地址是32位,端口是16位(端口号取值范围0~65535)
注:一般设置ip地址,协议以及端口号使用sockaddr_in结构而使用socket相关的函数需要地址参数时一般要把sockaddr_in结构强转为sockaddr结构!!(这样节省空间)
换言之,sockaddr是给操作系统用的。
//struct sockaddr 地址结构
struct sockaddr
{
sa_family_t sa_family; //保存使用的协议族,IPV4使用 AF_INET
char sa_data[14];
};
struct in6_addr
{
uint8_t s6_addr[16]; /* IPv6地址是128位(8×16) */
};
#define SIN6_LEN /* 用于编译时测试 */
struct sockaddr_in6
{
uint8_t sin6_len;
sa_family_t sin6_family;
in_port_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
};
sin6_family为地址族字段:IPv6为AF_INET6