20070611 BitConverter LittleEndian BigEndian
http://www.yippeesoft.com

网络字节顺序与主机字节顺的转换
              在写socket程序时要注意,如果要发送整型(short, int, long等)类型的数据,需要将这些值转换成网络字节顺序后才后再发送,同时接收方也要将网络字节顺序的值转为主机字节顺序的。System.Net.IPAddress类提供了HostToNetworkOrder 、HostToNetworkOrder 来完成相应的功能。

class Test
&leftsign;
public static byte[] Struct2Bytes(Object obj)
&leftsign;
int size = Marshal.SizeOf(obj);
byte[] bytes = new byte[size];
IntPtr arrPtr=Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);
Marshal.StructureToPtr(obj,arrPtr,true);
return bytes;
&rightsign;

public static Object Bytes2Struct(byte[] bytes)
&leftsign;
IntPtr arrPtr=Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);
return Marshal.PtrToStructure(arrPtr, typeof(Data));
&rightsign;
&rightsign;

反转整个一维 Array 中元素的顺序。

命名空间:System
程序集:mscorlib(在 mscorlib.dll 中)

// Example of the BitConverter::IsLittleEndian field.
using namespace System;
int main()
&leftsign;
   Console::WriteLine( "This example of the BitConverter::IsLittleEndian field "
   "generates \\nthe following output when run on "
   "x86-class computers.\\n" );
   Console::WriteLine( "IsLittleEndian:  &leftsign;0&rightsign;", BitConverter::IsLittleEndian );
&rightsign;

/*
This example of the BitConverter::IsLittleEndian field generates
the following output when run on x86-class computers.

IsLittleEndian:  True
*/

指示数据在此计算机结构中存储时的字节顺序(“Endian”性质)。
对于Unsigned Integer 和Interger字段,需要按照网络字节顺序和x86机器的字节编码顺序对照关系进行转换

转换网络字节主要是为廖网络交互,所谓网络字节顺序是一种网络传输的标准,如果你知道自己的程序要交互的对象认识你的host字节顺序,你也可以不转换。但还是建议转换,就像网络通讯需要tcp协议一样

最近使用C#进行网络开发,需要处理ISO8583报文,由于其中有些域是数值型的,于是在传输的时候涉及到了字节序的转换。字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有两种字节顺序,根据他们所处的位置我们分别称为主机节序和网络字节序。通常我们认为网络字节序为标准顺序,封包的时候,将主机字节序转换为网络字节序,拆包的时候要将网络字节序转换为主机字节序。原以为还要自己写函数,其实网络库已经提供了。 主机到网络:short/int/long IPAddress.HostToNetworkOrder(short/int/long) 网络到主机:short/int/long IPAddress.NetworkToHostOrder(short/int/long) 主机字节序指低字节数据存放在内存低地址处,高字节数据存放在内存高地址处,如: int x=1; //此时x为主机字节序:[1][0][0][0] 低位到高位 int y=65536 //此时y为主机字节序:[0][0][1][0] 低位到高位我们通过主机到网络字节序的转换函数分别对x和y进行转换得到他们对应的网络字节序值,网络节序是高字节数据存放在低地址处,低字节数据存放在高地址处,如: int m=IPAddress.HostToNetworkOrder(x); //此时m为主机[改为网络[/color:4d5c53bbac]]字节序:[0][0][0][1] 高位到低位 int n=IPAddress.HostToNetworkOrder(y); //此时n为主机[改为网络[/color:4d5c53bbac]]字节序:[0][1][0][0] 高位到低位 经过转换以后,我们就可以通过 byte[]btValue=BitConverter.GetBytes(m); 得到一个长度为4的byte数组,然后将这个数组设置到报文的相应位置发送出去即可。同样,收到报文后,可以将报文按域拆分,得到btValue,使用 int m=BitConverter.ToInt32(btValue,0);//从btValue的第0位开始转换得到该域的值,此时还不能直接使用,应该再用网络到主机字节序的转换函数进行转换: int x=IPAddress.NetworkToHostOrder(m); 这时得到的x才是报文中的实际值。

Han,

Intel CPUs are Little Endian. Unix variants tend to be Big Endian.

Your problem is sender:

byte[] fSize = new byte[4];
fSize = BitConverter.GetBytes(fInfo.Length);
sock.Send(fSize);

You are correctly sending your data size to the receiver so that your receiver knows how much data to expect.

 However, \’fSize\’  is not network byte ordered. You are sending a 32 bit value as 4 seperate bytes without care for network byte ordering. Further, your receiver does not account for netwrork byte ordering of that value and will misinterpret it.

I think that\’s the problem but it\’s almost 3 in the morning where I live so I will reserve further judgement till tomorrow.

当一个逻辑上长于一个字节的整形数据放置在内存中时(比如16位,32位,和64位的整数),计算机设计者需要考虑这些字节的存储顺序。一些体系结构的设计者选择了将字节的逻辑顺序与物理顺序一致,即将逻辑上较低的字节放置在物理上较低的字节上;另外一些设计者则选择了将字节的逻辑顺序与物理顺序相反,即将逻辑上较低的字节放置在物理上较高的字节上。前者被称为“little endian”,比如Intel x86系列;后者则被称为“big endian”,比如Motorola的PowerPC以及Sun Sparc。还有一些平台同时支持两种方案,由开发者决定使用哪一种。

历史博文

标签:,
十一月 12, 2007 at 10:31 上午 by yippee 1,015 次
Category: Info
Tags: ,