<aside> 💡 socket地址其实是一个结构体,封装端口号和IP等信息。后面的socket相关的api中需要使用到这个socket地址
</aside>
sockaddr
,其定义如下:#include <bits/socket.h>
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
};
typedef unsigned short int sa_family_t;
sa_family
成员是地址族类型(sa_family_t
)的变量。地址族类型通常与协议族类型对应
常见的协议族(protocol family,也称 domain)和对应的地址族如下所示:
sa_data
成员用于存放 socket 地址值
不同的协议族的地址值具有不同的含义和长度:
由上表可知,14 字节的 sa_data 根本无法容纳多数协议族的地址值
#include <bits/socket.h>
struct sockaddr_storage
{
sa_family_t sa_family;
unsigned long int __ss_align; // 用于内存对齐
char __ss_padding[ 128 - sizeof(__ss_align) ];
};
typedef unsigned short int sa_family_t;
<aside>
💡 一般使用 socketaddr_in
和 socketaddr_in6
来代替 socketaddr
</aside>
socketaddr_in
获取地址后,再使用(sockaddr *)
进行强制类型转换<aside>
💡 所有专用 socket 地址(以及 sockaddr_storage)类型的变量在实际使用时都需要转化为通用 socket 地址类型 sockaddr
(强制转化即可),因为所有 socket 编程接口使用的地址参数类型都是sockaddr
。
</aside>
#include <netinet/in.h>
struct sockaddr_in {
sa_family_t sin_family; // 地址族类型
in_port_t sin_port; // 端口号
struct in_addr sin_addr; // IP地址
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr) - __SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) - sizeof (struct in_addr)];
};
struct in_addr {
in_addr_t s_addr;
};
struct sockaddr_in6 {
sa_family_t sin6_family;
in_port_t sin6_port; /* Transport layer port # */
uint32_t sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* IPv6 scope-id */
};
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))