<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>以太之内 生存之上 &#187; byte order</title>
	<atom:link href="http://ixhan.com/tag/byte-order/feed/" rel="self" type="application/rss+xml" />
	<link>http://ixhan.com</link>
	<description>Live in your world, get owned in mine</description>
	<lastBuildDate>Mon, 26 Jul 2010 17:09:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>关于“字节序”</title>
		<link>http://ixhan.com/2009/10/little-about-byte-order/</link>
		<comments>http://ixhan.com/2009/10/little-about-byte-order/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 08:49:29 +0000</pubDate>
		<dc:creator>xhan</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Knowledge]]></category>
		<category><![CDATA[byte order]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://ixhan.com/?p=68</guid>
		<description><![CDATA[昨天纠正了长达几年的关于字节序的错误理解。 受到移位操作符的影响，一直认为在内存中数字的保存方式和显示的一样，比如一个2直接的short 9 ，保存在内存中应该是： 00 09 这种形式，因为这样移位才说的通。 否则如果按照低字节优先的方法 09 00 右移位就会出乱子了～ 结果昨天研究和服务器socket通讯的例子中 发现了个陌生函数 ：htonl  。 man （越来越喜欢命令行了）后发现是 host to network long(short) 的缩写 ，这下彻底困惑了。难道 c 在内存中的数据不是想象中的那样？ 最后K大侠亲自上阵，示范了使用GDB debug ，也帮我验证了我多年的错误观点： #include &#60;stdio.h&#62; int main() { int a = 8; char *p; p= (char*)&#38;a; a = a&#62;&#62;1; char *k = &#38;a; return 0; } gcc -g test.c   # [...]]]></description>
			<content:encoded><![CDATA[<p>昨天纠正了长达几年的关于字节序的错误理解。</p>
<p>受到移位操作符的影响，一直认为在内存中数字的保存方式和显示的一样，比如一个2直接的short 9 ，保存在内存中应该是：</p>
<p>00 09 这种形式，因为这样移位才说的通。 否则如果按照低字节优先的方法 09 00 右移位就会出乱子了～</p>
<p>结果昨天研究和服务器socket通讯的例子中 发现了个陌生函数 ：htonl  。</p>
<p>man （越来越喜欢命令行了）后发现是 host to network long(short) 的缩写 ，这下彻底困惑了。难道 c 在内存中的数据不是想象中的那样？</p>
<p>最后K大侠亲自上阵，示范了使用GDB debug ，也帮我验证了我多年的错误观点：</p>
<pre class="brush: cpp;">

#include &lt;stdio.h&gt;

int main()
{
 int a = 8;
 char *p;
 p= (char*)&amp;a;

 a = a&gt;&gt;1;
 char *k = &amp;a;

 return 0;
}
</pre>
<ul>
<li>gcc -g test.c   # -g 添加调试</li>
<li>gdb test.out   # init</li>
<li>b main          # add breakpoint at main function</li>
<li>run                 # just run until breakPoint occured</li>
<li>n                    # next</li>
</ul>
<p>逐次打印出 p 指针的值 p *(p++)   , 发现果然是地位在最前面的。<br />
不过对于移位操作就困惑了，难道这个操作不是直接在内存操作的？难道是先转成高位优先然后移位再转回来？<span id="more-68"></span></p>
<p>附一篇介绍比较详细的文章，<a href="http://www.blogjava.net/byterat/archive/2007/10/24/155471.html">来源</a></p>
<blockquote><p>BIG-ENDIAN（大字节序、高字节序）<br />
LITTLE-ENDIAN（小字节序、低字节序）<br />
主机字节序<br />
网络字节顺序<br />
JAVA字节序</p>
<p>1．BIG-ENDIAN、LITTLE-ENDIAN跟多字节类型的数据有关的比如int,short,long型，而对单字节数据byte却没有影 响。BIG-ENDIAN就是低位字节排放在内存的低端，高位字节排放在内存的高端。而LITTLE-ENDIAN正好相反。<br />
比如 int a = 0&#215;05060708<br />
在BIG-ENDIAN的情况下存放为：<br />
字节号 0 1 2 3<br />
数据 05 06 07 08<br />
在LITTLE-ENDIAN的情况下存放为：<br />
字节号 0 1 2 3<br />
数据 08 07 06 05</p>
<p>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。</p>
<p>3．所以在用C/C++写通信程序时，在发送数据前务必用htonl和htons去把整型和短整型的数据进行从主机字节序到网络字节序的转换，而接收数据 后对于整型和短整型数据则必须调用ntohl和ntohs实现从网络字节序到主机字节序的转换。如果通信的一方是JAVA程序、一方是C/C++程序时， 则需要在C/C++一侧使用以上几个方法进行字节序的转换，而JAVA一侧，则不需要做任何处理，因为JAVA字节序与网络字节序都是BIG- ENDIAN，只要C/C++一侧能正确进行转换即可（发送前从主机序到网络序，接收时反变换）。如果通信的双方都是JAVA，则根本不用考虑字节序的问 题了。</p>
<p>4．如果网络上全部是PowerPC,SPARC和Motorola CPU的主机那么不会出现任何问题，但由于实际存在大量的IA架构的CPU，所以经常出现数据传输错误。</p>
<p>5．文章开头所提出的问题，就是因为程序运行在X86架构的PC SERVER上，发送数据的一端用C实现的，接收一端是用JAVA实现的，而发送端在发送数据前未进行从主机字节序到网络字节序的转换，这样接收端接收到 的是LITTLE-ENDIAN的数据，数据解释自然出错。<br />
具体数据如下，实际发送的数据为23578<br />
发送端发送数据： 1A 5C<br />
接收端接收到数据后，按BIG-ENDIAN进行解释具体数据是多少？你们自己去计算并比较吧！</p>
<p>=============================================================================================== <span style="color: #333333;"><span style="color: #333333;">Big Endian and Little Endian</p>
<p>谈到字节序的问题，必然牵涉到两大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采 用big endian方式存储数据，而x86系列则采用little endian方式存储数据。那么究竟什么是big endian，什么又是little endian呢？</p>
<p>其实big endian是指低地址存放最高有效字节（MSB），而little endian则是低地址存放最低有效字节（LSB），即常说的低位在先，高位在后。<br />
用文字说明可能比较抽象，下面用图像加以说明。比如数字0&#215;12345678在两种不同字节序CPU中的存储顺序如下所示：</p>
<p>Big Endian</p>
<p>低地址                           高地址<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&gt;<br />
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br />
|     12     |      34    |     56      |     78    |<br />
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+</p>
<p>Little Endian</p>
<p>低地址                           高地址<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&gt;<br />
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<br />
|     78     |      56    |     34      |     12    |<br />
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+</p>
<p>从上面两图可以看出，采用big endian方式存储数据是符合我们人类的思维习惯的。而little endian，!@#$%^&amp;*，见鬼去吧 -_-|||<br />
</span></span></p></blockquote>
<h3  class="related_post_title">Related Posts</h3><ul class="related_post"><li><a href="http://ixhan.com/2010/03/tutorial-of-kissxml-iphone/" title="Tutorial of  kissXML(iPhone)">Tutorial of  kissXML(iPhone)</a></li><li><a href="http://ixhan.com/2010/02/work-with-passion/" title="work with passion">work with passion</a></li><li><a href="http://ixhan.com/2009/11/things-ive-done-in-past-5-months/" title="Things I&#8217;ve done int past 5 months">Things I&#8217;ve done int past 5 months</a></li><li><a href="http://ixhan.com/2009/10/how-software-companies-die/" title=" [转]软件公司是怎么死掉的"> [转]软件公司是怎么死掉的</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://ixhan.com/2009/10/little-about-byte-order/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
