socketaddr、sockaddr_in与addr_in
socketaddr与socketaddr_in的关系类似于基类和派生类的关系。addr_in是socketaddr_in中一个成员变量。
struct sockaddr { unsigned short sa_family; /* 地址族, AF_xxx */ char sa_data[14]; /* 14字节的协议地址*/ }; struct sockaddr_in { short int sin_family; /* 地址族,AF_xxx 在socket编程中只能是AF_INET */ unsigned short int sin_port; /* 端口号 (使用网络字节顺序) */ struct in_addr sin_addr; /* 存储IP地址 4字节 */ unsigned char sin_zero[8]; /* 总共8个字节,实际上没有什么用,只是为了和struct sockaddr保持一样的长度 */ }; struct in_addr就是32位IP地址。 struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; /* 按照网络字节顺序存储IP地址 */ } S_un; #define s_addr S_un.S_addr };
socketaddr与socketaddr_in可以进行类型转换。
inet_aton与inet_ntoa
inet_aton是将以点是分开的IP地址字符串转成in_addr对象。
inet_ntoa是将in_addr对象转成点分开的IP地址字符串。
inet_addr
inet_addr类似于inet_aton,是将以点分开的IP地址字符串转成in_addr对象。
inet_pton与inet_ntop
inet_pton是将点分开的IP地址字符串转成IPV4或IPV6的in_addr对象。
inet_ntop是将IPV4或IPV6的in_addr对象转成点分开的IP地址字符串。
这两个函数是随IPv6出现的函数,对于IPv4地址和IPv6地址都适用,函数中p和n分别代表表达(presentation)和数值(numeric)。地址的表达格式通常是ASCII字符串,数值格式则是存放到套接字地址结构的二进制值。
主机序与网络序列
不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序。最常见的有两种:
1. Little endian:将低序字节存储在起始地址
2. Big endian:将高序字节存储在起始地址
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。
htons、htonl、ntohs、ntohl
为了进行转换 bsd socket提供了转换的函数 有下面四个
htons 把unsigned short类型从主机序转换到网络序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序
网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)