每个协议族都定义了自己的套接字结构,这些结构均以sockaddr_开头,并对应每个协议族自己的唯一后缀
当向任意一个参数传递任何套接字函数时,套接字地址结构总是以引用形式传递
网络编程数据类型(POSIX规范)
数据类型 | 说明 | 头文件 |
---|---|---|
int8_t | 带符号8位整数 | <sys/types.h> |
uint8_t | 无符号8位整数 | <sys/types.h> |
int16_t | 带符号16位整数 | <sys/types.h> |
uint16_t | 无符号16位整数 | <sys/types.h> |
int32_t | 带符号32位整数 | <sys/types.h> |
uint32_t | 无符号32位整数 | <sys/types.h> |
sa_family_t | 套接字地址结构的地址族 | <sys/socket.h> |
socklen_t | 套接字地址结构的长度,一般为unit32_t | <sys/socket.h> |
in_addr_t | IPv4地址,一般为uint32_t | <netinet/in.h> |
in_port_t | TCP或UDP端口,一般为unit16_t | <netinet/in.h> |
IPv4套接字地址结构
//<netinet/in.h>
//固定长度-16字节
struct in_addr
{
in_addr_t s_addr; //32bit
};
struct sockaddr_in
{
uint8_t sin_len; //套接字长度
sa_family_t sin_family; //IPv4地址族"AF_INET"
in_port_t sin_port; //端口号
struct in_addr sin_addr; //IPV4地址
char sin_zero[8]; //未使用,置0
};
//in_addr_t数据类型必须是一个至少32位的无符号整数类型
//in_port_t必须是一个至少16位的无符号整数类型
//sa_family_t可以是任何无符号整数类型
//可以看到sin_addr是在in_addr结构中定义的,历史原因在这里不做探究
//但注意serv.sin_addr.s_addr和serv.sin_addr是完全不同的,一个传递32位整数,一个传递结构
//套接字地址结构仅在给定主机上使用,虽然IP地址和端口号在主机间传递,但是结构本身并不在主机之间传递
通用套接字地址结构
//解决传递指针时数据类型的处理问题
//<sys/socket.h>
struct sockaddr
{
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
//套接字函数被定义为以指向某个通用套接字地址结构的一个指针作为其参数之一
//如:int bind(int, struct sockaddr *, socklen_t);
//使用时需强制类型转换成通用套接字地址结构的指针
//如: struct sockaddr_in serv;
// bind(sockfd, (struct sockaddr *) &serv, sizeof(serv);
//在内核中检查sa_family确定套接字的真实类型
IPv6套接字地址结构
//<netinet/in.h>
//固定长度-28字节
struct in6_addr
{
unit8_t s6_addr[16]; //128位
};
#define SIN6_LEN //编译时确定
struct sockaddr_in6
{
uint8_t sin6_len;
sa_family_t sin6_family; //AF_INET6
in_port_t sin6_port;
unit32_t sin6_flowinfo //流标信息
struct in6_addr sin6_addr;
uint32_t sin6_scope_id; //为作用域设置接口
};
//如果系统支持长度字段,SIN6_LEN必须定义
//结构本身64位对齐,做过处理
//sin6_flowinfo分成两个字段
//低位20位是流标
//高序12位保留
//对于具备范围的地址,sin6_scope_id字段标识其范围,最常见的链路局部地址的接口索引
新的通用套接字地址结构
//<netinet/in.h>
struct sockaddr_storage
{
uint8_t ss_len; //依赖于实现
sa_family_t ss_family;
//用户透明
};
//a.可以满足所有套接字结构中最苛刻的对齐要求
//b.足够大
//其它的类型对用户透明,只有强制类型转换或者复制到某个确定的套接字结构中,才能访问其它字段