网络字节顺序和主机字节顺序的转换(htonsntohshtonlntohl).doc_第1页
网络字节顺序和主机字节顺序的转换(htonsntohshtonlntohl).doc_第2页
网络字节顺序和主机字节顺序的转换(htonsntohshtonlntohl).doc_第3页
网络字节顺序和主机字节顺序的转换(htonsntohshtonlntohl).doc_第4页
网络字节顺序和主机字节顺序的转换(htonsntohshtonlntohl).doc_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

网络字节顺序和主机字节顺序的转换(htons ntohs htonl ntohl) 什么是网络字节顺序和主机字节顺序呢?在进行网络编程时,需要进行转换以统一“格式”简述:网络字节顺序NBO(Network Byte Order):按从高到低的顺序存储,在网络上使用统一的网络字节顺序,可以避免兼容性问题。主机字节顺序(HBO,Host Byte Order):不同的机器HBO不相同,与CPU设计有关详解:不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序最常见的有两种1 Little endian:将低序字节存储在起始地址2 Big endian:将高序字节存储在起始地址LE little-endian最符合人的思维的字节序地址低位存储值的低位地址高位存储值的高位怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说低位值小,就应该放在内存地址小的地方,也即内存地址低位反之,高位值就应该放在内存地址大的地方,也即内存地址高位BE big-endian最直观的字节序地址低位存储值的高位地址高位存储值的低位为什么说直观,不要考虑对应关系只需要把内存地址从左到右按照由低到高的顺序写出把值按照通常的高位到低位的顺序写出两者对照,一个字节一个字节的填充进去例子:在内存中双字0x01020304(DWORD)的存储方式内存地址4000 4001 4002 4003LE 04 03 02 01BE 01 02 03 04例子:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为big-endian little-endian0x0000 0x12 0xcd0x0001 0x23 0xab0x0002 0xab 0x340x0003 0xcd 0x12x86系列CPU都是little-endian的字节序.网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。为了进行转换 bsd socket提供了转换的函数 有下面四个htons 把unsigned short类型从主机序转换到网络序htonl 把unsigned long类型从主机序转换到网络序ntohs 把unsigned short类型从网络序转换到主机序ntohl 把unsigned long类型从网络序转换到主机序在使用little endian的系统中 这些函数会把字节序进行转换在使用big endian类型的系统中 这些函数会定义成空宏同样 在网络程序开发时 或是跨平台开发时 也应该注意保证只用一种字节序 不然两方的解释不一样就会产生bug.函数例子解析之htonl()简述: 将主机的无符号长整形数转换成网络字节顺序。 #include u_long PASCAL FAR htonl( u_long hostlong); hostlong:主机字节顺序表达的32位数。注释: 本函数将一个32位数从主机字节顺序转换成网络字节顺序。返回值: htonl()返回一个网络字节顺序的值。inet_ntoa()简述:将网络地址转换成“.”点隔的字符串格式。 #include char FAR* PASCAL FAR inet_ntoa( struct in_addr in); in:一个表示Internet主机地址的结构。注释: 本函数将一个用in参数所表示的Internet地址结构转换成以“.” 间隔的诸如a.b.c.d”的字符串形式。请注意inet_ntoa()返回的字符串存放在WINDOWS套接口实现所分配的内存中。应用程序不应假设该 内存是如何分配的。在同一个线程的下一个WINDOWS套接口调用前,数据将保证是有效。返回值:若无错误发生,inet_ntoa()返回一个字符指针。否则的话,返回NVLL。其中的数据应在下一个WINDOWS套接口调用前复制出来。网 络中传输的数据有的和本地字节存储顺序一致,而有的则截然不同,为了数据的一致性,就要把本地的数据转换成网络上使用的格式,然后发送出去,接收的时候也 是一样的,经过转换然后才去使用这些数据,基本的库函数中提供了这样的可以进行字节转换的函数,如和htons( ) htonl( ) ntohs( ) ntohl( ),这里n表示network,h表示host,htons( ) htonl( )用于本地字节向网络字节转换的场合,s表示short,即对2字节操作,l表示long即对4字节操作。同样ntohs( )ntohl( )用于网络字节向本地格式转换的场合。附注:一、字节序定义字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数据当然就无需谈顺序的问题了)。其实大部分人在实际的开发中都很少会直接和字节序打交道。唯有在跨平台以及网络程序中字节序才是一个应该被考虑的问题。在所有的介绍字节序的文章中都会提到字节序分为两类:Big-Endian和Little-Endian。引用标准的Big-Endian和Little-Endian的定义如下:a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。c) 网络字节序:4个字节的32 bit值以下面的次序传输:首先是07bit,其次815bit,然后1623bit,最后是2431bit。这种传输次序称作大端字节序。由于 TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序,因此它又称作网络字节序。比如,以太网头部中2字节的“以太网帧类型”,表示后面数据的类型。对于ARP请求或应答的以太网帧类型来说,在网络传输时,发送的顺序是0x08,0x06。在内存中的映象如下图所示:栈底 (高地址)-0x06 - 低位0x08- 高位-栈顶 (低地址)该字段的值为0x0806。按照大端方式存放在内存中。二、高/低地址与高低字节首先我们要知道我们C程序映像中内存的空间布局情况:在C专家编程中或者Unix环境高级编程中有关于内存空间布局情况的说明,大致如下图:- 最高内存地址 0xffffffff| 栈底. 栈. 栈顶-|/|/NULL (空洞)/|/|- 堆-未初始化的数据-(统称数据段)初始化的数据-正文段(代码段)- 最低内存地址 0x00000000以上图为例如果我们在栈上分配一个unsigned char buf4,那么这个数组变量在栈上是如何布局的呢注1?看下图:栈底 (高地址)-buf3buf2buf1buf0-栈顶 (低地址)现在我们弄清了高低地址,接着来弄清高/低字节,如果我们有一个32位无符号整型0x12345678(呵呵,恰好是把上面的那4个字节buf看成一个整型),那么高位是什么,低位又是什么呢?其实很简单。在十进制中我们都说靠左边的是高位,靠右边的是低位,在其他进制也是如此。就拿 0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78。高低地址和高低字节都弄清了。我们再来回顾一下Big-Endian和Little-Endian的定义,并用图示说明两种字节序:以unsigned int value = 0x12345678为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf4来表示value:Big-Endian: 低地址存放高位,如下图:栈底 (高地址)-buf3 (0x78) - 低位buf2 (0x56)buf1 (0x34)buf0 (0x12) - 高位-栈顶 (低地址)Little-Endian: 低地址存放低位,如下图:栈底 (高地址)-buf3 (0x12) - 高位buf2 (0x34)buf1 (0x56)buf0 (0x78) - 低位-栈顶 (低地址)在现有的平台上Intel的X86采用的是Little-Endian,而像Sun的SPARC采用的就是Big-Endian。三、例子嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:内存地址 存放内容0x4001 0x120x4000 0x34而在Big-endian模式CPU内存中的存放方式则为:内存地址 存放内容0x4001 0x340x4000 0x1232bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:内存地址 存放内容0x4003 0x120x4002 0x340x4001 0x560x4000 0x78而在Big-endian模式CPU内存中的存放方式则为:内存地址 存放内容0x4003 0x780x4002 0x560x4001 0x340x4000 0x12四。不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。处理器操作系统字节排序Alpha全部 Little endianHP-PA NT Little endianHP-PA UNIX Big endianIntelx86全部 Little endian -x86系

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论