c语言 套接字地址结构
一、IPV4套接字地址结构
#include <netinet/in.h>
/**IPV4套接字地址结构**/
struct in_addr
{
in_addr s_addr; //32位IPV4地址,这是无符号整数,网络字节序
};
/*POSIX只关注sin_family,sin_port,sin_addr,所有网络套接字地质结构都至少16字节*/
struct sockaddr_in
{
uint8_t sin_len; //无符号八位整形,套接字地址长度(16字节)
sa_family_t sin_family; //unsigned short
in_port_t sin_port; //16位TCP、UDP端口号,网络字节序
struct in_addr sin_addr; //32位IPV4地址,这是个结构,网络字节序
char sin_zero[8]; //未使用
};
/**IPV4套接字地址结构**/
struct in_addr
{
in_addr s_addr; //32位IPV4地址,这是无符号整数,网络字节序
};
/*POSIX只关注sin_family,sin_port,sin_addr,所有网络套接字地质结构都至少16字节*/
struct sockaddr_in
{
uint8_t sin_len; //无符号八位整形,套接字地址长度(16字节)
sa_family_t sin_family; //unsigned short
in_port_t sin_port; //16位TCP、UDP端口号,网络字节序
struct in_addr sin_addr; //32位IPV4地址,这是个结构,网络字节序
char sin_zero[8]; //未使用
};
二、通用套接字地址结构
#include <sys/socket.h>
/***通用套接字地址结构***/
struct sockaddr
{
uint8_t sa_len;
sa_family_t sa_family; //地址族,AF_XXX
char sa_data[14]; //与协议相关的地址
};
三、IPV6套接字地址结构
#include <netinet/in.h>
/***IPV6套接字地址结构****/
struct in6_addr
{
uint8 s6_addr[16]; //128位IPV6地址,整数,网络字节序
};
#define SIN6_LEN //支持sin6_len的地址必须定义
struct sockaddr_in6
{
uint8_t sin6_len; //套接字地址长度(28字节)
sa_family_t sa6_family; //AF_INET6
in_port_t sin6_port; //端口
uint32 sin6_flowinfo; //流标,未定义
struct in6_addr sin6_addr; //IPV6地址,结构体
uint32_t sin6_scope_id//?;
};
四、新的通用套接字地址结构
/***新的通用套接字地址结构***/
struct sockaddr_storage
{
uint8_t ss_len; //本结构体的长度
sa_family_t ss_family; //地址族,AF_XXX
//可能还有其他字段
};
五、Unix域套接字结构
/**Unix域套接字结构**/
#include <sys/un.h>
struct sockaddr_un
{
sa_family_t sun_family; /*AF_LOCAL*/
char sun_path[104]; //路径名字符串
};
六、数据链路套接字地址
/***数据链路套接字地址***/
#include <net/if_dl.h> //interface
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]开始)
};
补充:通用套接字地址结构的作用
来自任何协议的套接字地址结构以引用形式(即指向该结构的指针)作为参数传递给套接字函数时,套接字函数必须处理来自任何协议的套接字地址结构,所以在声明的数据类型上存在问题。
1982年采取的办法是在定义一个通用套接字地址结构,于是套接字函数被定义为以指向某个通用套接字地址结构的一个指针作为其参数之一。比如bind函数:
int bind( int, struct sockaddr *, socklen_t );
struct sockaddr_in serv;
bind( sockfd, (struct sockaddr *)&serv, sizeof(serv) );
如果省略了强制类型转换部分(struct sockaddr *),C编译器会提示“warning:passing arg2 of ’bind’ from incompatible pointer type.”
所以,通用套接字地址结构的作用是对特定协议的套接字地址结构的指针执行强制类型转换。
补充:套接字地址结构命名的含义
sockaddr_in in其实是internet的缩写,所以这个命名的含义是“网际套接字地址结构”;
sin_family sin即sockaddr_in的缩写,其余类推。