UNIX几种套按字的结构说明
struct in_addr
{
//32 bit地IP4地址,使用网络字节序,故使用时要调用htonl函数或
//类似函数将其转换为网络字节序
in_addr_t s_addr;
};
struct sockaddr_in
{
uint8_t sin_len; //结构体长度,占1个字节,unsigned 8-bit
sa_family_t sin_family; //一般固定为AF_INET
in_port_t sin_port; //端口号,一般服务端需要指定,客户端自动分配
struct in_addr sin_addr; //IPv4地址,占4字节,为网络字节序
char sin_zero[8];
};
以上结构中,编程时只关注三个字段:sin_family、sin_port、sin_addr
其中sin_port和sin_addr要转换为网络字节序。
2. 通用套接字结构
在实现套接字接口函数的时候,这时候ANSI C标准还没有出来,向函数传递任何参数的类型还不是void*,
如何将套接字地址作为函数参数传递,同时又要兼容各种不同的套接字地址,在1982年的时候采用的一种办法,
就是定义一个通用套接字地址结构struct sockaddr,可以认为struct sockaddr_in结构只是Internet地址结构,
而struct sockaddr还兼容其它地址结构。
定义如下:
struct sockaddr
{
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
可以看到,两个结构大小完全一样,做了对齐处理,这就是为何网络编程的时候,调用有地址结构
的函数时,总是要将地址转化为(struct sockaddr*)地址类型,从而消除警告。
3. IPv6地址结构
struct in6_addr
{
uint8_t s6_addr[16]; //128 bit,使用网络字节序
};
struct sockaddr_in6
{
uint8_t sin6_len;
sa_family_t sin6_family;
in_port_t sin6_port;
uint32_t sin6_flowinfo;
struct_in6_addr sin6_addr;
uint32_t sin6_scope_id;
};
4. 新的通用套接字地址结构,同样是在IPv6中定义
struct sockaddr_storage
{
uint8_t ss_len;
sa_family_t ss_family;
};
5. Unix域套接字结构
头文件<sys/un.h>
struct sockaddr_un
{
sa_family_t sun_family;/*AF_LOCAL*/
char sun_path[104];//路径名字符串
};
6 数据链路套接字地址
头文件 <net/if_dl.h>
struct sockaddr_dl
{
uint8_t sdl_len;
sa_family_t sdl_family;//AF_LINK
uint16_t sdl_index;//>0,????
uint8_t sdl_type;//IFT_ETHER,ect.????
uint8_t sdl_nlen;//接口名称长度
uint8_t sdl_alen;//链路层地址长度
uint8_t sdl_slen;//链路层selector长度。??
char sdl_data[12];//接口名字(从sdl_data[0]开始)和链路层地址(从sdl_data[sdl_nlen]开始)
};
1. IPv4定义的套接字结构,头文件<netinet/in.h>
通常称为英特网套接字地址结构,定义如下struct in_addr
{
//32 bit地IP4地址,使用网络字节序,故使用时要调用htonl函数或
//类似函数将其转换为网络字节序
in_addr_t s_addr;
};
struct sockaddr_in
{
uint8_t sin_len; //结构体长度,占1个字节,unsigned 8-bit
sa_family_t sin_family; //一般固定为AF_INET
in_port_t sin_port; //端口号,一般服务端需要指定,客户端自动分配
struct in_addr sin_addr; //IPv4地址,占4字节,为网络字节序
char sin_zero[8];
};
以上结构中,编程时只关注三个字段:sin_family、sin_port、sin_addr
其中sin_port和sin_addr要转换为网络字节序。
2. 通用套接字结构
在实现套接字接口函数的时候,这时候ANSI C标准还没有出来,向函数传递任何参数的类型还不是void*,
如何将套接字地址作为函数参数传递,同时又要兼容各种不同的套接字地址,在1982年的时候采用的一种办法,
就是定义一个通用套接字地址结构struct sockaddr,可以认为struct sockaddr_in结构只是Internet地址结构,
而struct sockaddr还兼容其它地址结构。
定义如下:
struct sockaddr
{
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
可以看到,两个结构大小完全一样,做了对齐处理,这就是为何网络编程的时候,调用有地址结构
的函数时,总是要将地址转化为(struct sockaddr*)地址类型,从而消除警告。
3. IPv6地址结构
struct in6_addr
{
uint8_t s6_addr[16]; //128 bit,使用网络字节序
};
struct sockaddr_in6
{
uint8_t sin6_len;
sa_family_t sin6_family;
in_port_t sin6_port;
uint32_t sin6_flowinfo;
struct_in6_addr sin6_addr;
uint32_t sin6_scope_id;
};
4. 新的通用套接字地址结构,同样是在IPv6中定义
struct sockaddr_storage
{
uint8_t ss_len;
sa_family_t ss_family;
};
5. Unix域套接字结构
头文件<sys/un.h>
struct sockaddr_un
{
sa_family_t sun_family;/*AF_LOCAL*/
char sun_path[104];//路径名字符串
};
6 数据链路套接字地址
头文件 <net/if_dl.h>
struct sockaddr_dl
{
uint8_t sdl_len;
sa_family_t sdl_family;//AF_LINK
uint16_t sdl_index;//>0,????
uint8_t sdl_type;//IFT_ETHER,ect.????
uint8_t sdl_nlen;//接口名称长度
uint8_t sdl_alen;//链路层地址长度
uint8_t sdl_slen;//链路层selector长度。??
char sdl_data[12];//接口名字(从sdl_data[0]开始)和链路层地址(从sdl_data[sdl_nlen]开始)
};