目录
Linux套接字结构定义
Linux在头文件<sys/socket.h>中定义了一种通用的套接字结构类型,以供不同的协议调用:
struct sockaddr
{
unsigned short int sa_family;
unsigned char sa_data[14];
};
其中sa_family是套接字协议族地址类型,sa_data则是具体的协议地址(不同的协议族对应不同的地址结构)。
可选值 | 说明 |
AF_INET | IPv4协议 |
AF_INET6 | IPv6协议 |
AF_LOCAL | UNIX协议 |
AF_LINK | 链路地址协议 |
AF_KEY | 密钥套接字 |
除了sockaddr以外,Linux还在头文件<netinet/in.h>中定义了另外一种结构类型sockaddr_in,它和sockaddr等效且可以互相转换(需要显式转换),通常在涉及TCP/IP的编程协议中使用。
struct sockaddr_in
{
int sa_len; //长度单位,不必设置,通常情况下固定长度为16字节
short int sa_family; //地址族
unsigned short int sin_port; //端口号
struct in_addr sin_addr; //IP地址
unsigned char sin_zero[8]; //填充0以保持与struct sockaddr同样大小
};
struct sin_addr
{
in_addr_t s_addr; //32位IPv4地址,网络字节序
};
使用sockaddr_in的时候需要注意以下几点:
·结构sockaddr_in中的TCP或UDP端口号sin_port和IP地址sin_addr都是以网络字节序存储的,因此要注意格式统一
·32位的IPv4地址可以利用两种不同的方法使用,如sockaddr_in类型的结构体addr,要使用其IP地址可以是addr.sin_addr(此时引用的是结构体类型),也可以是addr.sin_addr.s_addr(此时引用的是整型)
·sin_zero不被使用,它是为了和通用套接字地址sockaddr保持一致而引入的,通常会被填充为0
Linux C的网络基础操作函数
字节顺序转换函数族
计算机的数据存储有两种形式:大端格式和小端格式
·大端格式:字数据的高位存储在低地址中
·小端格式:字数据的高位存储在高地址中
网络中的数据传输采用的是大端格式,而计算机操作系统既有大端格式(大型机)也有小端格式(一般PC机)。Linux在头文件<arpa/inet.h>提供了4个函数用于处理大端格式和小端格式的数据转换。
/*
函数名中,h代表host,n代表network,s代表short,l代表long
32位的long数据通常存放IP地址,16位的short数据通常存放端口号
这些函数调用成功后返回处理后的值,调用失败则返回-1
*/
uint32_t htonl(uint32_t hostlong); //将32位PC机数据(小端格式)转换为32位网络传输数据(大端格式)
uint16_t htons(uint16_t hostshort); //将16位PC机数据(小端格式)转换为16位网络传输数据(大端格式)
uint32_t ntohl(uint32_t netlong); //将32位网络传输数据转换为32位PC机数据
uint16_t ntohs(uint16_t netshort); //将16位网络传输数据转换为16位PC机数据
IP地址转换函数族
Linux在头文件<arpa/inet.h>提供了用于将“点分十进制”表示的IP地址与二进制表示的IP地址相互转换的函数族,这些函数包括inet_aton、inet_addr和inet_ntoa等。
·inet_aton函数用于将点分十进制数的IP地址转换成网络字节序的32位二进制数值。输入的点分十进制IP地址存放在参数straddr中,作为返回结果的二进制数值存放在addrptr中。
int inet_aton(const char *straddr, struct in_addr *addrptr);
·inet_ntoa函数调用的结果将作为函数的返回值返回给调用它的函数。
char *inet_ntoa(struct in_addr inaddr);
·int_addr函数的功能与inet_aton函数相同,但是结果传递的方式不同。结果以返回值的形式返回。
in_addr_t inet_addr(const char *straddr);
域名转换函数
Linux在头文件<netdb.h>中