套接口编程简介
1.套接口地址结构
(1).IPv4套接口地址结构
IPv4套接口地址结构通常称为"网际套接口地址结构",以“sockaddr_in”命名,定义在头文件<netinet/in.h>中。
struct in_addr {
in_addr_t s_addr; //32-bit IPv4 address.network byte ordered
};
struct sockaddr_in {
uint8_t sin_len; //length of structure
sa_family_t sin_family; //AF_INET
in_port_t sin_port; //16 bit tcp or udp port number.network byte ordered
struct in_addr sin_addr; //32-bit IPv4 address. network byte ordered
char sin_zero[8]; //unused
};
数据类型 | 说明 | 头文件 |
int8_t | 带符号的8位整数 | <sys/types.h> |
uint8_t | 无符号的8位整数 | <sys/types.h> |
int16_t | 带符号的16位整数 | <sys/types.h> |
uint16_t | 不带符号的16位整数 | <sys/types.h> |
int32_t | 带符号的32位整数 | <sys/types.h> |
uint32_t | 不带符号的32位整数 | <sys/types.h> |
sa_family_t | 套接口地址结构的地址族 | <sys/socket.h> |
socklen_t | 套接口地址结构的长度,一般为uint32_t | <sys/socket.h> |
in_addr_t | IPv4地址,一般为uint32_t | <netinet/in.h> |
in_port_t | tcp或udp端口,一般为uint16_t | <netinet/in.h> |
(2)通用套接口地址结构
struct sockaddr {
uint8_t sa_len;
sa_family_t sa_family; //address family:AF_xxx
char sa_data[4]; //protocol-specific address
};
从应用程序开发人员的观点看,这些通用的套接口地址结构的唯一用途是给指向特定于协议的地址结构的指针转换类型。
从内核的角度看,使用指向通用套接口地址结构的指针的原因是:内核必须依据调用者的指针,将其转换为struct sockaddr*类型,然后检查sa_family的值来确定结构的类型。
(3)还有ipv6套接口地址结构和新的通用套接口地址结构。
2.值-结果参数
当把套接口地址结构传递给套接口函数时,总是通过指针来传递的,即传递的是一个指向结构的指针。结构的长度也作为参数传递时,其传递的方式取决于结构传递方向:
1).从进程到内核传递套接口地址结构,有3个函数:bind, connect, sendto,这3个函数的一个参数是指向套接口地址结构的指针,另一个是结构的整数大小。所以从进程到内核要确切拷贝多少数据是知道的。
2).从内核到进程传递套接口地址结构有4个函数:accept,recvfrom,getsockname,getpeername。这4个函数的两个参数是:指向套接口地址结构的指针和指向表示结构大小的整数的指针。
为何将结构大小由整数给为指向整数的指针?因为当函数被调用时,结构大小是一个值(此值告诉内核该结构的大小,使内核在写此结构时不至于越界),当函数返回时,结构大小又是一个结果(它告诉进程内核在此结构中确切存储了多少信息)。这种参数类型叫做值-结果参数。