网络编程基础(3):什么是sockaddr和sockaddr_in?区别是什么?两者该如何使用,如何相互转换呢?

相信大家在初学网络编程基础的时候,经常性的会遇到sockaddr和sockaddr_in,并且两者之间还转换来转换去的。那么sockaddr和sockaddr_in到底是什么呢?

一、什么是sockaddr和sockaddr_in

其实,sockaddr和sockaddr_in就是两个用于处理网络通信地址的结构体。sockaddr是在IPv4协议诞生之前就存在了,而sockaddr_in是在IPv4协议诞生之后被提出的,两者在数据结构上具有差异。下图为sockaddr和sockaddr_in的数据结构图。

网络编程基础(3):什么是sockaddr和sockaddr_in?区别是什么?两者该如何使用,如何相互转换呢?_第1张图片

二、sockaddr和sockaddr_in区别是什么

根据上面的数据结构图,我们可以得到两者的结构体定义:

(1)、sockaddr结构体

struct sockaddr { 
    sa_family_t sa_family; //代表16位地址类型,若为IPv4,那么输入的参数就为:AF_INET,若为IPv6,那么输入的参数就为:AF_INET6    
    char sa_data[14]; //共有14字节,包含2字节端口号和4字节IP地址和8字节填充 
};

(2)、sockaddr_in结构体

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该如何使用

讲到这里,相信大家对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如何相互转换

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

好了讲到这里,相信大家已经柳暗花明又一村了,非常感谢各位观众老爷的观看,我们一起学习一起进步!

你可能感兴趣的:(网络通信编程基础,网络,c++,tcp/ip)