博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于网络传输字节顺序的问题: hton? or ntoh?
阅读量:5253 次
发布时间:2019-06-14

本文共 1753 字,大约阅读时间需要 5 分钟。

小知识:字节顺序 

很少有人关心字节顺序(Byte Ordering),因为它真的很少用到。何为字节顺序呢?让我们先来看一个例子,假设现在有一个WORD类型的变量,它的值为0x7788,那么它在内存中是怎么存放的呢?
内存中:

低地址 高地址

0x77 0x88

 

高地址 低地址

0x77 0x88

图3.7 两种字节顺序 
事实上,对于不同的CPU、不同的操作系统,图3.7中的两种字节顺序都是可能的。如果像图3.7左边那样:高字节在前,低字节在后,则这种字节顺序称作为big-endian;如果像图3.7右边那样:低字节在前,高字节在后,则这种字节顺序称作为little-endian。 
表3.1 常见的CPU、操作系统上使用的字节顺序 
CPU 操作系统 字节顺序 
x86 (Intel、AMD等) 所有 little-endian 
DEC Alpha 所有 little-endian 
HP-PA NT little-endian 
HP-PA UNIX big-endian 
SUN SPARC 所有 big-endian 
MIPS NT little-endian 
MIPS UNIX big-endian 
PowerPC NT little-endian 
PowerPC 非NT big-endian 
RS/6000 UNIX big-endian 
Motorola m68k 所有 big-endian 
一般来说,我们不用关心字节顺序问题,除非要涉及到跨平台的通信和资源共享,比如本章将要介绍的网络编程(网络传输协议TCP/IP采用的是big-endian)。假设现在要在使用不同字节顺序的机器之间传输和交换数据,那该怎么办呢?(同样的数据,不同的机器可能有不同的理解,岂不是有悖初衷!)有两种方法,一种是全部转换成文本来传输,另一种是双方都按照某一方的字节顺序来传输(这时就有一个不同字节顺序之间的相互转换问题)。 
Socket编程中经常采用第二种方法。整个传输过程如下:发送端将本机的数据转换成网络的字节顺序(调用API函数htonl或htons),然后发送;接收端收到网络数据后,先将数据转换成本机的字节顺序(调用API函数ntohl或ntohs),然后再进行其它操作——如此就能保证“会议精神”在通信双方的正确传达了!这个过程中用到的几个API函数:ntohl、htonl、ntohshtons,名字都差不多,很难区分。但是如果知道了它们的来历,问题也就不存在了:n是network,网络的意思;h是host,本地主机的意思。ntohl,就是将32位的u_long类型的数据从网络字节顺序转换成本机字节顺序(htonl的字节顺序转换过程与ntohl相反);ntohs,就是将16位的u_short类型的数据从网络字节顺序转换成本机字节顺序(htons的字节顺序转换过程与ntohs相反)。 
最后还有一个小问题:如何知道本机的字节顺序呢?有个很简单的方法,如下: 
BOOL IsLittleEndian(void) 
WORD wValue = 0x5678; 
return (*((BYTE*)&wValue) == 0x78); 
另外,TCPServer程序和TCPClient程序在实现时都用到了一个工具类UNetwork。这个类实现了两个静态成员函数:GetHostInfo和DumpSocketError。前者用于获取本地主机的IP地址、机器名等信息,后者用于程序调试时跟踪Socket错误。特别是DumpSocketError函数,非常实用。因为Socket程序的调试一般都比较麻烦,这时DumpSocketError函数就能将整型Socket错误码转换成容易理解的字符串说明形式输出,非常方便! 

 

但是有个问题是为什么在创建socket的时候或者bind的时候需要htons来转换字节序,而以后在send函数发送data的时候却不需要转换了呢?我想会不会是:底层协议进行了转换,但是在创建的时候学要转换一下来“握手”,在“达成共识”以后由协议(底层程序)来完成这个工作

 

转载于:https://www.cnblogs.com/number10/p/3931138.html

你可能感兴趣的文章
CentOS
查看>>
Linux pipe函数
查看>>
java equals 小记
查看>>
爬虫-通用代码框架
查看>>
2019春 软件工程实践 助教总结
查看>>
YUV 格式的视频呈现
查看>>
Android弹出框的学习
查看>>
现代程序设计 作业1
查看>>
在android开发中添加外挂字体
查看>>
Zerver是一个C#开发的Nginx+PHP+Mysql+memcached+redis绿色集成开发环境
查看>>
多线程实现资源共享的问题学习与总结
查看>>
Learning-Python【26】:反射及内置方法
查看>>
torch教程[1]用numpy实现三层全连接神经网络
查看>>
java实现哈弗曼树
查看>>
转:Web 测试的创作与调试技术
查看>>
python学习笔记3-列表
查看>>
程序的静态链接,动态链接和装载 (补充)
查看>>
关于本博客说明
查看>>
线程androidAndroid ConditionVariable的用法
查看>>
stap-prep 需要安装那些内核符号
查看>>