系统调用函数

1.字节顺序和转换函数

先来了解一个概念:大端模式和小端模式 大端模式是指高字节数据存放在低地址处,低字节数据存放在高地址处. 小端模式是指低字节数据放在内存的内存低地址处,高字节数据存放在内存的高地址处. 在网络上传输数据时,由于数据传输的两端可能对应不同的硬件平台,采用的存储字节的顺序也可能不一致,因此TCP/IP协议规定了在网络上必须采用网络字节顺序(大端模式),对于char 型数据,由于其只占一个字节,所以不存在这个问题,所以一般都把缓冲区定义成char 型,而对于IP地址等非char型的数据, 必须在数剧发送到网络前将其转换成大端,在接收数据前 再将其转换成符合接收端主机的存储模式. linux 下有4个大小端的转换函数. #include <netinet/in.h> uint32_t  htonl(uint32_t  hostlong); uint16_t htons(uint16_t  hostshort); uint32_t  ntohl(uint32_t  netlong); uint16_t  ntohs(uint16_t  netshort); htonl表示host to network long:用于将主机unsigned int 型数据转换成网络字节顺序, htons表示host to network short:用于将主机unsigned short型数据转换为网络字节顺序 ntohl表示network to host long:用于就将网络unsigned int 型数据转换为主机的字节顺序. ntohs表示network to host short:用于将网络unsigned short 型数据转换为主机字节顺序.

2. inet系列函数

通常我们习惯用字符串形式的网络地址,然而在网络上进行数据通信时,需要使用的是二进制形式且为网络字节顺序的IP地址,linux 提供了一系列函数. #include <sys/socket.h> #include <netinet.h> #include <arpa/inet.h> int  inet_aton(const  char *cp,struct in_addr  *inp); inet_aton()将参数cp所指的字符串形式的IP地址转换为二进制的网络字节顺序的IP地址,转换的结果保存在inp所指向的空间里.函数执行成功返回非0,失败返回0; in_addr_r  inet_addr(const char*cp); inet_aton()将参数cp所指的字符串形式的IP地址转换为二进制的网络字节顺序的IP地址.执行成功返回转换后的结果,参数无效返回INADDR_NONE,该函数已经过时, in_addr_t  inet_network(const  char *cp); inet_network()将参数cp所指的字符串形式的网络地址转换为主机字节顺序形式的二进制ip地址,执行成功返回转换后的结果,参数无效返回-1; char *inet_ntoa(struct in_addr in); 该函数将把值为in的网络字节顺序形式的二进制IP地址转换成以"."分隔的字符串形式,执行成功返回结果字符串的指针,参数无效返回NULL; struct in_addr_inet_makeaddr(int net,int host); 该函数把网络号为参数net,主机号为host的两个地址组合成一个网络地址,如net取0xac11(172.17.0.0,主机字节顺序),host取0xf283(0.0.242.131,主机字节顺序形式),则组合后的地址172.17.242.131 .并表示为网络字节顺序形式0x83f211ac. int addr_t  inet_lnaof(struct in_addr  in); 该函数从参数in 中提取出主机地址,执行成功返回主机字节顺序形式的主机地址. in_addr_t  inet_netof(str) 该函数从参数in中提取出网络地址,执行成功主机字节顺序形式的网络地址. 看个例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 int main()
{
	char buffer[32];
	int ret=0;
	int host=0;
	int network=0;
	unsigned int address = 0;
	struct in_addr  in;
	in.s_addr = 0;
//输入一个以".分隔的字符串形式的IP地址"
printf("请输入你的IP地址:");
fgets(buffer,32,stdin);
buffer[31]='\0';
//示例使用inet_aton函数;
if((ret=inet_aton(buffer,&in)) ==0)  //int inet_aton(const char *cp,struct in_addr *inp);成功返回0值
{
	printf("inet_aton:\t无效的IP地址\n");
}
else
{
	printf("inet_aton:\t0x%x\n",in.s_addr);
}
//示例inet_addr()函数
if((address=inet_addr(buffer))==INADDR_NONE) //in_addr inet_addr(const char *cp); 成功返回转换后的结果,失败返回INADDR_NONE;
{
	printf("inet_addr:\t无效的IP地址\n");
}
else
{
	printf("inet_addr:\t0x%x\n",address);
}
//示例inet_network()函数
if((address=inet_network(buffer))==-1)  //in_addr inet_network(const char *cp);成功返回转换的结果,失败返回 -1;
{
	printf("inet_network:\t无效的IP地址\n");
}
else
{
	printf("inet_network:\t0x%x\n",address);
}
//示例inet_ntoa()函数
if(inet_ntoa(in)==NULL)    //char *inet_ntoa(struct in_addr in);成功返回结果字符串的指针,失败返回NULL;
{
	printf("inet_ntoa:\t无效的IP地址\n");
}
else
{
	printf("inet_ntoa:\t%s\n",inet_ntoa(in));
}
//示例使用inet_lnaof()与inet_netof()函数
host=inet_lnaof(in);//in_addr inet_lnaof(struct in_addr in)转换为主机字节顺序的主机地址
network=inet_netof(in); //in_addr inet_netof(struct in_adr in)转换为主机顺序的网络地址
printf("inet_lnaof:\t0x%x\n",host);
printf("inet_netof:\t0x%x\n",network);
in=inet_makeaddr(network,host);// struct in_addr inet_makeaddr(int net,int host);返回结构体;
printf(" inet_makeaddr:0x%x\n",in.s_addr);
return 0;
}

结果:

请输入你的IP地址:192.168.3.4
inet_aton:	0x403a8c0
inet_addr:	0x403a8c0
inet_network:	0xc0a80304
inet_ntoa:	192.168.3.4
inet_lnaof:	0x4
inet_netof:	0xc0a803
 inet_makeaddr:0x403a8c0

再此运行255.255.255.255

yang@liu:~/syc/第11章$ ./a.out
请输入你的IP地址:255.255.255.255
inet_aton:	0xffffffff
inet_addr:	无效的IP地址
inet_network:	无效的IP地址
inet_ntoa:	255.255.255.255
inet_lnaof:	0xff
inet_netof:	0xffffff
 inet_makeaddr:0xffffffff

可以看出inet_addr() 和函数inet_network()函数会把255.255.255.255当做无效的地址;

你可能感兴趣的:(系统调用函数)