【Linux网络编程】常见 Socket 地址结构
【1】IPv4套接字地址结构
struct sockaddr_in {
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port; /* 端口号 */
struct in_addr sin_addr; /* 网络地址 */
/* 填充结构体空间与 `struct sockaddr' 大小一致 */
unsigned char sin_zero[sizeof (struct sockaddr) -
sizeof (sa_family_t) -
sizeof (in_port_t) -
sizeof (struct in_addr)];
};
typedef uint32_t in_addr_t;
struct in_addr {
in_addr_t s_addr; /* IPv4 地址 */
};
【2】IPv6套接字地址
struct sockaddr_in6 {
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* 传输层端口号 */
uint32_t sin6_flowinfo; /* IPv6 流信息 */
struct in6_addr sin6_addr; /* IPv6 地址 */
uint32_t sin6_scope_id; /* IPv6 域Id */
};
struct in6_addr { /* IPv6 地址结构体 */
union {
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};
【3】UNIX域套接字地址结构
struct sockaddr_un {
sa_family_t sun_family; //AF_LOCAL
char sun_path[ 104 ]; //路径名,必须以空字符结尾
}
【4】数据链路套接字地址结构
struct sockaddr_dl {
uint8_t sdl_len;
sa_family_t sdl_family; //AF_LINK
uint16_t sdl_index; //系统分配的索引
uint8_t sdl_type; //类型
uint8_t sdl_nlen; //名称长度,起始位置为 sdl_data[ 0 ]
uint8_t sdl_alen; //链路层地址长度
uint8_t sdl_slen; //链路层选择器长度
char sdl_data[ 12 ]; //最小的工作区间,内存大小可扩充,
//包含名字与链路层地址信息
}
【5】通用套接字地址结构
/* Structure large enough to hold any socket address
(with the historical exception of AF_UNIX). 128 bytes reserved. */
/* 该结构体足够大,能够容纳任何 socket 地址,预留 128 个字节 */
#if ULONG_MAX > 0xffffffff
# define __ss_aligntype __uint64_t
#else
# define __ss_aligntype __uint32_t
#endif
#define _SS_SIZE 128
#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype)))
struct sockaddr_storage
{
sa_family_t ss_family; /* Address family */
__ss_aligntype __ss_align; /* 强制对齐,Force desired alignment. */
char __ss_padding[_SS_PADSIZE];
};
【6】不同套接字地址结构体比较
参考
本博客为博主的学习实践总结,并参考了众多博主的博文,在此表示感谢,博主若有不足之处,请批评指正。
【1】UNIX网络编程
【2】网络编程中4个重要的地址数据结构