﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-自由的天空-文章分类-Network</title><link>http://www.blogjava.net/kata/category/8669.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 19:53:27 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 19:53:27 GMT</pubDate><ttl>60</ttl><item><title>网络字节序的问题</title><link>http://www.blogjava.net/kata/articles/36210.html</link><dc:creator>kata</dc:creator><author>kata</author><pubDate>Mon, 20 Mar 2006 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/kata/articles/36210.html</guid><wfw:comment>http://www.blogjava.net/kata/comments/36210.html</wfw:comment><comments>http://www.blogjava.net/kata/articles/36210.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kata/comments/commentRss/36210.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kata/services/trackbacks/36210.html</trackback:ping><description><![CDATA[出处:<font color="#0e3e92">ChinaUnix.net<br /></font><br />最近接触到网络字节序的概念 查了查资料 不是很明白 先引用一段材料： <br /><br />字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序，通常有小端、大端两种字节顺序。小端字节序指低字节数据存放在内存低地址处，高字节数据存放在内存高地址处；大端字节序是高字节数据存放在低地址处，低字节数据存放在高地址处。基于X86平台的PC机是小端字节序的，而有的嵌入式平台则是大端字节序的。因而对int、uint16、uint32等多于1字节类型的数据，在这些嵌入式平台上应该变换其存储顺序。通常我们认为，在空中传输的字节的顺序即网络字节序为标准顺序，考虑到与协议的一致以及与同类其它平台产品的互通，在程序中发数据包时，将主机字节序转换为网络字节序，收数据包处将网络字节序转换为主机字节序。 <br /><br />在本LINUX的书里介绍到INTEL的CPU使用的小端字节序 其他比MOTOROLA  <br />68000系列CPU使用的是大端字节序 如果不转换 将数据通过网络发出时 比如MOTOROLA发一个16位数据：0X1234 传送到INTEL时  <br />就被INTEL解释为0X3412 也就是4660成了13330 所以有时候需要一些函数来进行大小端字节序的转换 <br /><br />关于这大小字节序的概念不是很想的明白 数据在 <br />内存里是具体怎么存放的形式？为什么会有CPU解释的不同？数据不是按12345678……这样的顺序一直排列的么？希望大人赐教 谢谢<br /><br /><table style="WORD-BREAK: break-all; BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" width="100%" align="center" border="0"><tbody><tr><td><small> xuechao 回复于：2003-11-20 17:11:57</small></td></tr><tr><td>没人顶吗？各位给条路啊<br /><br /></td></tr><tr><td><small> 流氓无产者 回复于：2003-11-20 18:57:00</small></td></tr><tr><td>不就是大小印地安记法吗 <br />1）从低到高存 (liittle edian) <br />例:0x1234 <br />内存中是0x34 0x12 <br />2）从高到低存 (big edian) <br />例:0x1234 <br />内存中是0x12 0x34<br /><br /></td></tr><tr><td><small> sky-walker 回复于：2003-11-20 19:43:46</small></td></tr><tr><td>如:   一个多字节值 0xFECDBA98,内存从地址100开始存放 <br /><br />降序:      FE | CD | BA  |  98----&gt;对应地址100 |  101  | 102 | 103 <br /><br />升序:     98 |  BA  |  CD  |  FE ----&gt;same above <br /><br />注意,我们的书写表示法是从低字节位---&gt;高字节位 <br /><br /><br />至于为什么CPU解释不同,可能是由于不同的体系构架在起始竞争时人为地制造 <br /><br />和对手不兼容性......害的我们这么惨,一遇到移植就要注意这个 :twisted:  <br /><br />C代码的移植相对简单原因之一就是由于C的连续存储数据永远保持从低地址到高 <br /><br />地址的索引........<br /><br /></td></tr><tr><td><small> xuechao 回复于：2003-11-20 22:32:27</small></td></tr><tr><td>小端字节序就是升序排列那种？ <br />我们的书写表示法是从低字节位---&gt;高字节位   这个是什么意思呢？难道FECDBA98是从低到高（从左到右）吗？ <br /><br />还有它排列是按单个字节来 还是按数据类型的？比如说是INT型就按两个两个排 就象0X1234 和0X3412 而不是0X1234 和0X4321？<br /><br /></td></tr><tr><td><small> sky-walker 回复于：2003-11-20 23:32:56</small></td></tr><tr><td>"我们的书写表示法是从低字节位---&gt;高字节位 这个是什么意思呢？难道FECDBA98是从低到高（从左到右）吗？" <br /><br />否 <br /><br /><br />"还有它排列是按单个字节来 还是按数据类型的" <br /><br />对于多字节数据才有这么一出 <br /><br />这样理解吧 <br />譬如: <br />内存地址生长方向为:  从左到右  由低到高(这是不变的) <br /><br />数据为:                    0x89ABCDEF <br /><br />降序(Big-endian)大端字节序     存储时        由左到右 <br /><br />升序(Little-endian)小端字节序   存储时        由右向左 <br /><br />可以自己编一个小程序验证一下(用C的数组) <br /><br />更简单的调用VC里的checkEndian()<br /><br /></td></tr><tr><td><small> xuechao 回复于：2003-11-21 13:22:25</small></td></tr><tr><td>understood <br />thanx!!<br /><br /></td></tr><tr><td><small> wqch 回复于：2004-04-27 15:05:29</small></td></tr><tr><td>关于网络字节序和主机字节序的转换    ytjia（原作）   <br />   <br />关键字     网络字节序，Socket  <br />   <br /><br /><br />主机和网络字节序的转换 <br /><br />最近使用C#进行网络开发，需要处理ISO8583报文，由于其中有些域是数值型的，于是在传输的时候涉及到了字节序的转换。字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序，通常有两种字节顺序，根据他们所处的位置我们分别称为主机节序和网络字节序。 <br /><br />通常我们认为网络字节序为标准顺序，封包的时候，将主机字节序转换为网络字节序，拆包的时候要将网络字节序转换为主机字节序。原以为还要自己写函数，其实网络库已经提供了。 <br /><br />主机到网络：short/int/long IPAddress.HostToNetworkOrder(short/int/long) <br /><br />网络到主机：short/int/long IPAddress.NetworkToHostOrder(short/int/long) <br /><br />  <br /><br />主机字节序指低字节数据存放在内存低地址处，高字节数据存放在内存高地址处，如： <br /><br />int x=1;    //此时x为主机字节序：[1][0][0][0] 低位到高位 <br /><br />int y=65536 //此时y为主机字节序：[0][0][1][0] 低位到高位 <br /><br />我们通过主机到网络字节序的转换函数分别对x和y进行转换得到他们对应的网络字节序值，网络节序是高字节数据存放在低地址处，低字节数据存放在高地址处，如： <br /><br />int m=IPAddress.HostToNetworkOrder(x); <br /><br />//此时m为主机[[color=red:4d5c53bbac]改为网络[/color:4d5c53bbac]]字节序：[0][0][0][1] 高位到低位 <br /><br />int n=IPAddress.HostToNetworkOrder(y); <br /><br />//此时n为主机[[color=red:4d5c53bbac]改为网络[/color:4d5c53bbac]]字节序：[0][1][0][0] 高位到低位 <br /><br />  <br /><br />经过转换以后，我们就可以通过 <br /><br />byte[]btValue=BitConverter.GetBytes(m); <br /><br />得到一个长度为4的byte数组，然后将这个数组设置到报文的相应位置发送出去即可。 <br /><br />同样，收到报文后，可以将报文按域拆分，得到btValue，使用 <br /><br />int m=BitConverter.ToInt32(btValue,0);//从btValue的第0位开始转换 <br /><br />得到该域的值，此时还不能直接使用，应该再用网络到主机字节序的转换函数进行转换： <br /><br />int x=IPAddress.NetworkToHostOrder(m); <br /><br />这时得到的x才是报文中的实际值。</td></tr></tbody></table><img src ="http://www.blogjava.net/kata/aggbug/36210.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kata/" target="_blank">kata</a> 2006-03-20 10:02 <a href="http://www.blogjava.net/kata/articles/36210.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>