Linux网络编程API三方面:
(1)socket地址API:socket最开始的含义为一个IP地址好端口对(IP,PORT)。它唯一的表示了使用TCP通信的一端,即socket地址
(2)socket基础API:socket主要的API都定义在<sys/socket.h>中,包括创建socket、命名socket、监听socket、接受连接、发起连接、读写数据、获取地址信息、检测外带标记,以及读取和设置socket选项
(3)网络信息API:Linux提供了一套网络信息API,以实现主机名和IP地址之间的转换,以及服务名称和端口号之间的转换。定义在<netdb.h>中
一、socket地址API
1.主机字节序和网络字节序
(1)字节序问题:CPU累加器一次至少能装载4字节(即一个整数),但这4个字节在内存中排列的顺序将影响它被累加器装载成整数的值。检测机器字节序代码。字节序分为大端字节序(big endian)和小端字节序(little endian)
(a)大端字节序:一个整数的高位字节(23bit—31bit)存储在内存的低地址处,低位字节(0—7bit)存储在内存的高地址处;
(b)小端字节序:整数的高字节存储在内存的高地址处,而低位字节则存储在内存的低地址处。现代PC大多采用小端字节序,因此小端字节序又称为主机字节序。
(c)当格式化数据,在使用两个不同字节序的主机之间直接传递时,接收端必然解释错误。解决方法:发送端将要发送的数据转化成为大端字节序后发送,而接收端当知道接受的数据总是大端字节序再根据自身采用的字节序决定是否进行转换。因此大端字节序又称为网络字节序,给所有接收数据的主机提供了一个正确解释收到的格式化数据保证。
注意:在同一台机器上两个进程之间通信也要考虑字节序问题,编写程序的语言不同。
2.Linux提供4个函数来完成主机字节序和网络字节序之间的转换:
#include<netinet/in.h>
1)unsigned long int htonl(unsigned long int hostlong);//将long的主机字节序转化为网络字节序数据。
2)unsigned short int htons(unsigned short int hostshort);
3)unsigned long int ntohl(unsigned long int netlong);
4)unsigned short int ntohl(unsigned short int netshort);
二、通用socket地址:#include<bitssocket.h>
socket网络编程接口中表示socket地址的是结构体socketaddr
struct sockaddr
{ sa_family_t sa_family;//地址族类型(sa_family_t)的变量
char sa_data[14];//用于存放socket地址值,不同协议族的地址值具有不同含义和长度
}
地址族类型通常与协议族类型对应;
宏PF_*和AF_*都定义在<bitssocket.h>中,而后者与前者完全相同,可以混用。
协议族及其地址值
协议族 | 地址值含义和长度 |
PF_UNIX | 文件的路径名,长度可达到108字节 |
PF_INET | 16bit端口号和32bit IPv4地址,共6字节 |
PF_INET6 | 16bit端口号和32bit流标识,128bit IPv6地址,32bit范围ID,共26字节 |
由于sa_data无法容纳多数协议族的地址值,定义新的通用地址结构体:
struct sockaddr_storage
{
sa_family_t sa_family;
unsigned long int __ss_align;
char __ss_padding[128-sizeof(__ss_align)];
}
此结构体足够空间用于存放地址值,而且内存对齐。