Linux编程-sockaddr和sockaddr_in区别

本文最后更新于:1 年前

sockaddr在头文件#include <sys/socket.h>中定义,sockaddr的缺陷是:sa_data把目标地址和端口信息混在一起了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* POSIX.1g specifies this type name for the `sa_family' member.  */
typedef unsigned short int sa_family_t;

/* This macro is used to declare the initial common members
of the data types used for socket addresses, `struct sockaddr',
`struct sockaddr_in', `struct sockaddr_un', etc. */

#define        __SOCKADDR_COMMON(sa_prefix) \
sa_family_t sa_prefix##family

/* Structure describing a generic socket address. */
struct sockaddr
{
__SOCKADDR_COMMON (sa_);        /* Common data: address family and length. */
char sa_data[14];                /* Address data. */
};

sockaddr_in在头文件#include<netinet/in.h>或#include <arpa/inet.h>中定义,该结构体解决了sockaddr的缺陷,把port和addr 分开储存在两个变量中

1
2
3
4
5
6
7
8
9
10
11
12
13
/* Structure describing an Internet socket address.  */
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
in_port_t sin_port; /* Port number. */
struct in_addr sin_addr; /* Internet address. 32位unsigned int的IPv4地址 */

/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr)
         - __SOCKADDR_COMMON_SIZE
         - sizeof (in_port_t)
         - sizeof (struct in_addr)];
};

​ 二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。 sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。 sockaddr_in 是internet环境下套接字的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作,使用sockaddr_in来建立所需的信息,最后使用类型转化就可以了。一般先把sockaddr_in变量赋值后,强制类型转换后传入用sockaddr做参数的函数:sockaddr_in用于socket定义和赋值;sockaddr用于函数参数。