网络编程(7)字节序对跨平台数据传输的影响
来源:互联网 发布:灯具安装网络接单平台 编辑:程序博客网 时间:2024/04/27 04:11
一。从服务端发送整数到客户端为例,看看字节序的应用。
二。什么是字节序?
三。什么是网络字节序
四。如何确定本机的大小端
一。从服务端发送整数到客户端为例,看看字节序的应用。
服务端代码节选:
//发送整数 //调用 send_num(sClient,num,sizeof(int)); void send_num(int sockfd,int *data,int nbytes) { int sendData; //主机字节序转为网络字节序 sendData = htons(*data); //发送给客户端 //send(sockfd,sendData,nbytes,0); write(sockfd,sendData,nbytes); }客户端代码节选:
//接收整数 void recv_num(int sockfd,int *data) { int tmpData; //发送给客户端 //recv(sockfd,&tmpData,nbytes,0); read(sockfd,&tmpData,nbytes); //网络字节序转为主机字节序 data = htons(*tmpData); }上面代码可以放入我前面的socket例子中测试下。
注意,字符串型的无须转换,整型的则需要。 原因之一是网络传输是以字节为单位进行的。由sizeof(char)可知,一个字符对应一个字节,
无须转换, 但sizeof(int)会发现占四位,说明保存一个整型需要占4个字节。这时需要将其从本地字节序转为网络字节序才能正确的传输。
二。什么是字节序?
不同的计算机系统采用不同的字节序存储数据,同样一个4字节的32位整数,在内存中存储的方式就不同. 字节序分为小尾字节序(Little Endian)和大尾字节序(Big Endian), Intel处理器大多数使用小尾字节序, Motorola处理器大多数使用大尾(Big Endian)字节序;
小尾就是低位字节排放在内存的低端,高位字节排放在内存的高端。
大尾就是高位字节排放在内存的低端,低位字节排放在内存的高端。
可以用printf("%02x,%02x,%02x,%02x",p,p+1,p+2,p+3);类似的方式打印出来做对比。
三。什么是网络字节序
TCP/IP各层协议将字节序定义为大尾,因此TCP/IP协议中使用的字节序通常称之为网络字节序。
这意味着,在数据流传输过程中,本地数据流需转为网络字节序传输, 然后网络数据流再转换成本地字节序数据流。
所以c语言提供了一堆转换函数:
htons() : 将16位无符号整数从本地字节序转换成网络字节序
htonl() : 将32位无符号整数从本地字节序转换成网络字节序
ntohs() : 将16位无符号整数从网络字节序转换成本地字节序
ntohl() : 将32位无符号整数从网络字节序转换成本地字节序
不过没有针对64位整型的转换函数,而这个还是常用到的。
转一个64位字节序转换函数(http://www.cppblog.com/aa19870406/archive/2012/06/20/179517.html 找的):
unsigned long long ntohll(unsigned long long val) { if (__BYTE_ORDER == __LITTLE_ENDIAN) { return (((unsigned long long )htonl((int)((val << 32) >> 32))) << 32) | (unsigned int)htonl((int)(val >> 32)); } else if (__BYTE_ORDER == __BIG_ENDIAN) { return val; } } unsigned long long htonll(unsigned long long val) { if (__BYTE_ORDER == __LITTLE_ENDIAN) { return (((unsigned long long )htonl((int)((val << 32) >> 32))) << 32) | (unsigned int)htonl((int)(val >> 32)); } else if (__BYTE_ORDER == __BIG_ENDIAN) { return val; www.2cto.com } }四。如何确定本机的大小端
这个网上一大堆,下面找的两种方法展示得很清楚:
第一种方法:
思路:利用指针的强制类型转换
#include <stdio.h> int main(void){ int data1 = 0x12345678; int i; for(i=0; i<4; i++) { printf("%#x ----->%p\n",*((char *)&data1 + i),(char *)&data1 + i); } return 0;}第二种方法
思路:利用共用体所有数据都从同一地址开始存储这个特性来区分。
#include <stdio.h>int main(void){ int i; union endian { int data; char ch; }test; test.data = 0x12345678; if(test.ch == 0x78) { printf("little endian!\n"); } else { printf("big endian!\n"); } for(i=0; i<4; i++) { printf("%#x ------- %p\n",*((char *)&test.data + i),(char *)&test.data + i); } return 0;}运行上面任意一种方法,都能很清楚的展示出字节的顺序来出。
总之,字节序,大小端转换在网络通讯中非常重要,特别是跨平台时要特别注意。
另,可以看看另一篇看看字节序对Oracle数据库的传输表空间的影响:<<传输表空间技术及字节序对跨平台迁移的影响>>
MAIL: xcl_168@aliyun.com
BLOG: http://blog.csdn.net/xcl168
- 网络编程(7)字节序对跨平台数据传输的影响
- 网络编程之字节序对跨平台数据传输的影响
- 【网络编程】数据传输时的字节序
- 传输表空间技术及字节序对跨平台迁移的影响
- 网络编程(9)内存对齐对跨平台通讯的影响
- 跨平台网络数据传输过程中的主机字节顺序和网络字节顺序
- 字节序及对堆栈的影响
- 字节序及对堆栈的影响
- 关于网络数据传输大小端字节序的转换
- 智能手机对网络的影响
- 为什么主机或网络字节序对字符串不影响结果
- 网络编程--字节序
- cpu对编程的影响
- socket网络编程中的数据传输的问题
- 网络编程 UDP 数据传输
- 不同平台字节序影响位字段封包
- 日食追踪:对移动网络的影响
- 调整参数对bp网络的影响
- $250000投资的陷阱(转自创业孵化器Year One Labs的联合创始人Ben Yoskovitz)
- java学习笔记<八>final修饰符
- GO和C++代码对比,GO少个25%代码
- 山理工acm各位数相加
- 第三周:接口
- 网络编程(7)字节序对跨平台数据传输的影响
- JAVA读写资源文件
- NVelocity介绍
- JAVA UUID 生成
- Rust运行时指南(官方文档翻译)
- 冒泡排序
- 6. redhat grep、egrep、fgrep
- 开源一个适用于双Y轴的iOS折线图控件
- Centos Fedora 编译R