大多数套接字函数都需要一个指向套接字地址结构的指针作为参数。每个协议簇抵都定义它自己的套接字地址结构
这些结构的名字均以sockaddr_开头,并以对应每个协议簇的唯一后缀结尾
1.IPv4套接字地址结构
IPv4套接字地址结构通常称为:网际套接字地址结构
它以sockaddr_in命名
struct in_addr{
in_addr_t s_addr;//32位无符号整数类型
};
struct sockaddr_in{
unit8_t sin_len;//套接字地址结构长度 它是一个无符号短整形 可以不设置它的值
sa_family_t sin_family;//套接字地址结构的地址簇 任何无符号整数类型
in_port_t sin_port;//TCP或UDP端口号 网络字节序 至少16位的无符号整数类型
struct in_addr sin_addr;//IPv4地址 网络字节序
cahr sin_zero[8];//不是必须要 保持对齐
};
2.通用套接字地址结构
当作为一个参数传递进任何套接字函数时,套接字地址结构总是以引用形式(也就是以指向该结构的指针)来传递
然而以这样的指针作为参数之一的任何套接字函数必须处理来自所支持的任何协议簇的套接字地址结构
有了ANSI C后解决办法很简单:void *是通用的指针类型
然而套接字函数在ANSI C之前定义的 采取的方法是定义一个通用套接字地址结构
struct sockaddr{
uint8_t sa_len;
sa_family_t sa_family;//地址簇类型
char sa_data[14];//
}
于是套接字函数被定义为以指向某个通用套接字地址结构的一个指针作为其参数之一
正如bind函数的原型
int bind(int ,struct sockaddr *, sockle _t);
这就要求对这些函数的任何调用都必须要将指向特定于协议的套接字地址结构的指针进行强制类型转换
变成指向某个通用套接字地址结构的指针
struct sockaddr_in serv;
bind (sockfd,(struct sockaddr*) &serv,sizeof(serv));
如果我们省去了其中的类型强制转换部分
并假设系统的头文件中有 bind函数的一个原型
那么C编译器就会产生这样的警告:把不兼容的指针类类型传递给bind函数
从应用层开发人员来看:这些通用套接字地址结构的唯一用途就是对指向特定于协议的套机诶在地址结构的指针执行类型强制转换
从内核角度来看:内核必须取调用者的指针,把它强制类型转换为struct sockaddr * 类型,然后检查其中sa_family字段的值来确定这个结构的真实类型