相信大家在初学网络编程基础的时候,经常性的会遇到sockaddr和sockaddr_in,并且两者之间还转换来转换去的。那么sockaddr和sockaddr_in到底是什么呢?
其实,sockaddr和sockaddr_in就是两个用于处理网络通信地址的结构体。sockaddr是在IPv4协议诞生之前就存在了,而sockaddr_in是在IPv4协议诞生之后被提出的,两者在数据结构上具有差异。下图为sockaddr和sockaddr_in的数据结构图。
根据上面的数据结构图,我们可以得到两者的结构体定义:
struct sockaddr {
sa_family_t sa_family; //代表16位地址类型,若为IPv4,那么输入的参数就为:AF_INET,若为IPv6,那么输入的参数就为:AF_INET6
char sa_data[14]; //共有14字节,包含2字节端口号和4字节IP地址和8字节填充
};
struct sockaddr_in {
sa_family_t sin_family; //代表16位地址类型,若为IPv4,那么输入的参数就为:AF_INET,若为IPv6,那么输入的参数就为:AF_INET6
in_port_t sin_port; //代表16位端口号
struct in_addr sin_addr; //代表32位IP地址,是一个结构体
};
sockaddr_in结构体内部定义的结构体in_addr定义如下:
struct in_addr {
uint32_t s_addr; //32位无符号整型IP地址
};
讲到这里,相信大家对sockaddr和sockaddr_in已经有了初步了解,但是具体如何使用,可能还是一头雾水。别急!我举个例子,相信大家就能完全理解了。且看下面的代码(PS:注释很重要哦!)
#define SERVER_PORT 666 //定义一个端口号
struct sockaddr_in server_addr; //定义一个sockaddr_in结构体
server_addr.sin_family=AF_INET; //这里相当于定义结构体sockaddr_in 的第1个参数,将IPv4作为地址类型
server_addr.sin_port=htons(SERVER_PORT); //这里相当于定义结构体sockaddr_in 的第2个参数,SERVER_PORT为上面定义的端口号,htons是将主机字节序转换为网络字节序,具体原理以及为什么要转换请看我的上一篇文章:https://mp.csdn.net/mp_blog/creation/editor/135142053
server_addr.sin_addr.s_addr=htonl(INADDR_ANY); 这里相当于定义结构体sockaddr_in 的第3个参数,INADDR_ANY是一个宏定义,代表本机所有IP地址,为0.0.0.0
PS:htons和htonl的使用请看我的上一篇文章:CSDN
sockaddr和sockaddr_in两结构体之间该如何转换呢?非常简单,且看:
struct sockaddr_in server_addr_in; //定义一个sockaddr_in结构体
struct sockaddr server_addr; //定义一个sockaddr_in结构体
(struct sockaddr *)&server_addr_in //将sockaddr_in转换为sockaddr
(struct sockaddr_in *)&server_addr //将sockaddr转换为sockaddr_in
好了讲到这里,相信大家已经柳暗花明又一村了,非常感谢各位观众老爷的观看,我们一起学习一起进步!