Linux底层的socket地址
2021-07-29 本文已影响0人
Jamza
socket 地址
在 socket 网络编程接口中,表示 socket 地址的结构体是通用的 sockaddr:
#include <bits/socket.h>
struct sockaddr
{
sa_family_t sa_family;
char sa_data[14];
}
显然,14 字节的 sa_data 无法完全容纳多数协作族的地址值,在 Linux 中,定义了新的通用的 socket 地址:
#include <bits/socket.h>
struct sockaddr_storage
{
sa_family_t sa_family;
unsigned long int __ss_align;
char __ss_padding[128-sizeof(__ss_align)];
}
以上的两个同样的 socket 地址不够友好,比如设置或者获取 IP 地址与端口号,需要繁琐的位操作。因此,Linux 为各个协议族提供了专门的 socker 地址结构体。
UNIX 本地域协议族使用的 socket 地址结构体:
#include <sys/un.h>
struct sockaddr_un
{
sa_family_t sa_family; /* AF_UNIX */
char sun_path[108]; /* 文件路径名 */
}
IPv4 协议族使用的 socket 地址结构体:
#include <netinet/in.h>
struct sockaddr_in
{
sa_family_t sin_family; /* AF_INET */
u_int16_t sin_port;
struct in_addr sin_addr; /* 网络字节序表示 */
}
struct in_addr
{
u_int32_t s_addr; /* 网络字节序表示 */
}
IPv6 协议族使用的 socket 地址结构体:
#include <netinet/in.h>
struct sockaddr_in6
{
sa_family_t sin6_family; /* AF_INET6 */
u_int16_t sin6_port;
u_int32_t sin6_flowinfo;
struct in6_addr sin6_addr;
u_int32_t sin6_scope_id;
}
struct in6_addr
{
unsigned char sa_addr[16]; /* 网络字节序表示 */
}
以上所有的协议族专用地址结构(包括 sockaddr_storage)类型的变量,在实际使用时都需要转换为通用 socket 地址类型 sockaddr,使用强制类型转换即可。