考虑到我的数据类型的字节序,我遇到了问题。我必须使用 TCP/IP 通过以太网发送数据。然而,字节顺序在发送时需要是大端,而在接收时是大端。因此,在使用此类发送之前,我尝试反转所有日期:
class ReverseBinaryReader : BinaryReader
{
private byte[] a16 = new byte[2];
private byte[] ua16 = new byte[2];
private byte[] a32 = new byte[4];
private byte[] a64 = new byte[8];
private byte[] reverse8 = new byte[8];
public ReverseBinaryReader(System.IO.Stream stream) : base(stream) { }
public override int ReadInt32()
{
a32 = base.ReadBytes(4);
Array.Reverse(a32);
return BitConverter.ToInt32(a32, 0);
}
public override Int16 ReadInt16()
{
a16 = base.ReadBytes(2);
Array.Reverse(a16);
return BitConverter.ToInt16(a16, 0);
}
[ . . . ] // All other types are converted accordingly.
}
在我像这样分配转换后的值之前,它工作正常:
ReverseBinaryReader binReader = new ReverseBinaryReader(new MemoryStream(content));
this.Size = binReader.ReadInt16(); // public short Size
例如,如果我想将字节:0x00、0x02 保存为大端,我希望在内存中是这样的:0x0200,但是 Size 的短值将变为 0x0002。这是为什么?
有什么想法吗?谢谢,同行
//编辑 2:
为了更清楚地说明问题,我将尝试展示一个示例:
public class Message {
public short Size;
public byte[] Content;
public Message(byte[] rawData)
{
ReverseBinaryReader binReader = new ReverseBinaryReader(new MemoryStream(rawData));
this.Size = binReader.ReadInt16(); // public short Size
this.Content = binReader.ReadBytes(2); // These are not converted an work just fine.
}
}
public class prog {
public static int main()
{
TCPClient aClient = new TCPClient("127.0.0.1",999); // Async socket
aClient.Send(new Message(new byte[] { 0x00, 0x02 } );
}
}
编辑:
将此移至顶部,因为这是实际答案。
我不得不盯着它看很长时间,但这是你错误的根源。
- 你的初始数组是 { 0x00, 0x02 } 在 LE 中是 0x0200,BE 是 0x0002
- 你通过网络发送它,并读取前两个字节仍然是 { 0x00, 0x02 }
- 你反转它给你 {0x02, 0x00} LE 是 0x0002,BE 是 0x0200
- 您的体系结构是 Little Endian,因此您得到“正确”的结果 0x0002。
因此错误在您的测试数组中。您可以通过检查 BitConverter 上的 IsLittleEndian 属性来验证您的架构是否为小端。
=====================================================
下面的代码是为了帮助澄清,而不是回答你的直接问题。并表明 BitConverter 在所有架构上都是可预测的。
using System;
namespace BitConverterTest
{
class Program
{
static void Main(string[] args)
{
UInt32 u32 = 0x01020304;
byte[] u32ArrayLittle = {0x04, 0x03, 0x02, 0x01};
byte[] u32ArrayBig = {0x01, 0x02, 0x03, 0x04};
if (BitConverter.IsLittleEndian)
{
if (BitConverter.ToUInt32(u32ArrayLittle, 0) != u32)
{
throw new Exception("Failed to convert the Little endian bytes");
}
Array.Reverse(u32ArrayBig); // convert the bytes to LittleEndian since that is our architecture.
if (BitConverter.ToUInt32(u32ArrayBig, 0) != u32)
{
throw new Exception("Failed to convert the Big endian bytes");
}
} else
{
Array.Reverse(u32ArrayLittle); // we are on a big endian platform
if (BitConverter.ToUInt32(u32ArrayLittle, 0) != u32)
{
throw new Exception("Failed to convert the Little endian bytes");
}
if (BitConverter.ToUInt32(u32ArrayBig, 0) != u32)
{
throw new Exception("Failed to convert the Big endian bytes");
}
}
}
}
}
我是一名优秀的程序员,十分优秀!