编写网络应用时的字节序问题
来源:互联网 发布:部分便笺的元数据 编辑:程序博客网 时间:2024/05/10 01:48
昨天,看我们的程序员写的一段网络应用中数据接收部分的代码,该段代码用于从一个用C++编写的应用中接收数据,其中有一个数据项是整型数,在代码中是这样做的:接收过来后,对数据流中的这个整型数,做一次字节序的转换,第0个字节跟第3个字节互换,第1个字节跟第2个互换。经过跟程序员的交流,他跟我结实说不这么变换数据不对,具体原因也不知道为什么。
要把这个问题搞清楚,需要从BIG-ENDIAN、LITTLE-ENDIAN、主机字节序、网络字节顺序和JAVA字节序开始,然后在针对以上问题进行分析。
1.BIG-ENDIAN、LITTLE-ENDIAN跟多字节类型的数据有关的比如int,short,long型,而对单字节数据byte却没有影响。LITTLE-ENDIAN就是低位字节排放在内存的低端,高位字节排放在内存的高端。而BIG-ENDIAN正好相反。
比如 int a = 0x05060708
在BIG-ENDIAN的情况下存放为:
字节号 0 1 2 3
数据 05 06 07 08
在LITTLE-ENDIAN的情况下存放为:
字节号 0 1 2 3
数据 08 07 06 05
2.BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有关的,每一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN、。IA架构的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola处理器。这其实就是所谓的主机字节序。而网络字节序是指数据在网络上传输时是大头还是小头的,在Internet的网络字节序是BIG-ENDIAN。所谓的JAVA字节序指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。
3.所以在用C/C++写通信程序时,在发送数据前务必用htonl和htons去把整型和短整型的数据进行从主机字节序到网络字节序的转换,而接收数据后对于整型和短整型数据则必须调用ntohl和ntohs实现从网络字节序到主机字节序的转换。如果通信的一方是JAVA程序、一方是C/C++程序时,则需要在C/C++一侧使用以上几个方法进行字节序的转换,而JAVA一侧,则不需要做任何处理,因为JAVA字节序与网络字节序都是BIG-ENDIAN,只要C/C++一侧能正确进行转换即可(发送前从主机序到网络序,接收时反变换)。如果通信的双方都是JAVA,则根本不用考虑字节序的问题了。
4.如果网络上全部是PowerPC,SPARC和Motorola CPU的主机那么不会出现任何问题,但由于实际存在大量的IA架构的CPU,所以经常出现数据传输错误。
5.文章开头所提出的问题,就是因为程序运行在X86架构的PC SERVER上,发送数据的一端用C实现的,接收一端是用JAVA实现的,而发送端在发送数据前未进行从主机字节序到网络字节序的转换,这样接收端接收到的是LITTLE-ENDIAN的数据,数据解释自然出错。
具体数据如下,实际发送的数据为23578
发送端发送数据: 1A 5C
接收端接收到数据后,按BIG-ENDIAN进行解释具体数据是多少?你们自己去计算并比较吧!
- 编写网络应用时的字节序问题
- delete 应用时应注意的问题
- MySQL 开发应用时的超时问题
- Minifying Angular应用时产生的问题
- 做Camera应用时遇到的问题
- 用VB编写COM+应用时碰到问题?
- 解决MUI编写iOS应用时,视频自动全屏问题
- 上传应用时查看是否网络有问题
- Solaris上开发J2EE应用时中文问题的解决
- Xcode5.x编译64位应用时的出错问题
- Xcode5.x编译64位应用时的出错问题
- 如何解决Xcode5上传应用时找不到图标的问题。
- Eclipse开发Android应用时遇到的问题以及解决方法
- 使用mina部署rails应用时遇到的问题们
- 网络字节序的问题
- 网络字节序的问题
- jQuery应用时的记录
- 指针应用时的注意事项
- 又见民工荒
- 收集一些js学习网站
- sendmessage
- 从php向JavaScript变量传值
- [Oracle] DBA 常用脚本二
- 编写网络应用时的字节序问题
- 排序算法分析
- 数据库文件BAK的还原
- 通用分页
- 对创业的果断够自信幽默!——《赢在中国》史上最牛最搞笑选手
- Problem about the Format of Title-in Interactive Reporting
- 金融危机与王永庆的冰淇淋哲学
- 经典英文歌曲,爆好听!
- DC故障恢复记录