字节顺序的验证
可以自己编一个小程序验证一下(用C的数组)
更简单的调用VC里的checkEndian()
Intel处理器的字节顺序是和DEC VAX处理器的字节顺序一致的。因此它与68000型处理器以及Internet的顺序是不同的,所以用户在使用时要特别小心以保证正确的顺序。
任何从Windows Sockets函数对IP地址和端口号的引用和传送给Windows Sockets函数的IP地址和端口号均是按照网络顺序组织的,这也包括了sockaddr_in结构这一数据类型中的IP地址域和端口域(但不包括sin_family域)。 如何手算主机字节顺序转换为网络字节顺序?
假设某16位的整数,主机字节顺序的值是21,那么它的网络字节顺序是多少? 解决的步骤是:
1、将21化成二进制,二进制,如果不足16位就在其前面补0,补满16位。
21转换成二进制是:10101,在它前面补0,补满16位后就得到:
00000000#00010101
2、将这个16位二进制字符平分成两段,每段8位
0000000 000010101 == > 00000000#00010101
3、颠倒这两段的顺序,然后去掉第一个字符“1”前面的0,化成十进制就得到了网络字节顺序的值了。
00000000#00010101颠倒后:00010101#00000000
即00 01 01 01 00 000000
去掉第一个“1”前面的0得到:10 10 10 00 00 00 0
化成十进制得到:5376
通过这个程序可以进行验证: #include<stdio.h>#include<string.h>#include<netdb.h>intmain(void){structservent*server=NULL;charsername[16]=\0;charproname[4]=\0;printf(请输入服务名称:);gets(sername);printf(请输入使用的协议:);gets(proname);//如果能够通过getserbyname函数找到结果,就输出结果,否则报错if((server=getservbyname(sername,proname))!=NULL){printf(网络服务端口:\n);printf(网络字节顺序值:%d\n,server->s_port);printf(主机字节顺序值:%d\n,ntohs(server->s_port));}else{printf(该服务不存在\n);}return0;}编译后,按提示输入ftp和tcp,就得到网络字节顺序值是5376,主机字节顺序值是21。
16位的转换函数:ntohs和htons ntohs(network to host short)是将网络字节顺序转换为主机字节顺序,返回值是一个16位的整数,即2个字节长度的整数(1字节=8位)short int,也可以写作uint16_t。 htons(host to network short)是将主机字节顺序转换为网络字节顺序,返回值也是一个16位的整数short int。
32位转换函数ntohl和htonl。 ntohl(network to host long)是将网络字节顺序转换为主机字节顺序,返回值是一个16位的整数,即2个字节长度的整数(1字节=8位)long int,也可以写作uint32_t。 htonl(host to network long)是将主机字节顺序转换为网络字节顺序,返回值也是一个16位的整数long int。 IP地址使用的是32位的无符号整数,所以,在对IP地址进行处理的时候,就需要用到32位的转换了。 一个点分十进制的IP地址是192.168.0.1,还原成原来的二进制原码是:
11000000 10101000 0000000 00000 0001
这是主机字符顺序存储的值。 将其按照每个字节分隔开来,即每8位分隔开来,得到: 11000000 10101000 00000000 00000001 将这4段二进制编码进行完全颠倒,就得到了网络字节顺序: 00000001000000001010100011000000 去掉第一个字符“1”前面无效的0,得到: 10 00 00 00 01 01 01 00 01 10 00 00 0
化成十进制得到:16820416 inet_addr函数可以将一个点分十进制的IP地址转换成网络字节顺序的长整形十进制值。同样的,inet_ntoa函数将网络字节顺序的长整形十进制数值的IP地址转换成点分十进制。 将一个点分十进制的IP地址转换成它的二进制原码 分析:用inet_addr函数,转换点分十进制的IP为网络字节顺序的长整型十进制数值后,再用ntohl函数将其转换成主机字节顺序的长整型整数,然后使用一个自定义函数将这个主机字节顺序的长整形整数转换成二进制。 #include<stdio.h>#include<sys/socket.h>#include<netdb.h>#include<arpa/inet.h>#include<netinet/in.h>#include<string.h>//十进制转二进制函数,参数为无符号超长整形(防止溢出)voiddec(constunsignedlonglongintx){if(x/2>0){dec(x/2);printf(%d,x%2);}else{printf(%d,x);}}intmain(void){charipaddr[15]=\0;unsignedlonglonginthostaddr=0;//主机字节IP的值printf(请输入IP地址:);gets(ipaddr);hostaddr=ntohl(inet_addr(ipaddr));printf(IP地址的网络字节顺序的值:%ld\n,inet_addr(ipaddr));//调用dec函数,为了防止溢出将hostaddr强制转换成无符号超长整形后再转换成二进制printf(二进制形式是:\n);dec((unsignedlonglongint)hostaddr);printf(\n);return0;}
2022-05-15 广告