在允许我们通过UDP / IP控制它的硬件文档中, 我发现了以下片段:

  

在这个通信协议中,DWORD是4字节数据,WORD是2字节数据,   BYTE是单字节数据。存储格式为小端,即4字节(32位)数据存储为:d7-d0,d15-d8,d23-d16,d31-d24;双字节(16位)数据存储为:d7-d0,d15-d8。

我想知道这是如何转换为C#的? 在发送之前我是否必须转换内容? 例如,如果我想通过32位整数或4个字符的字符串发送?

有帮助吗?

解决方案

C#本身没有定义字节序。但是,无论何时转换为字节,您都可以做出选择。 BitConverter 类有 IsLittleEndian 字段告诉你它将如何表现,但它没有给出选择。 BinaryReader / BinaryWriter也是如此。

我的 MiscUtil 库有一个EndianBitConverter类,可以让您定义字节序; BinaryReader / Writer有类似的等价物。没有在线使用指南我很害怕,但它们很简单:)

(EndianBitConverter还有一个功能,它在普通的BitConverter中不存在,它在字节数组中就地进行转换。)

其他提示

您也可以使用

IPAddress.NetworkToHostOrder(...)

简称,int或long。

Re little-endian,简短的回答(我需要做什么)是“可能不是,但这取决于你的硬件”。您可以查看:

bool le = BitConverter.IsLittleEndian;

根据所说的内容,您可能想要反转部分缓冲区。另外,Jon Skeet还有这里的特定端转换器(寻找EndianBitConverter)。

请注意,itaniums(例如)是big-endian。大多数英特尔都是小端的。

重新启用特定的UDP / IP ......?

您需要了解网络字节顺序以及CPU字节顺序。

通常对于TCP / UDP通信,您始终使用 htons 功能(以及 ntohs 及其相关功能)。

通常网络顺序是big-endian,但在这种情况下(出于某种原因!),comms是小端,所以这些功能不是很有用。这很重要,因为你不能假设他们已经实现的UDP通信遵循任何其他标准,如果你有一个big-endian架构也会让生活变得困难,因为你无法用 htons 包装所有内容应该: - (

但是,如果您来自intel x86架构,那么您已经是小端,所以只需发送数据而不进行转换。

如果您正在解析并且性能并不重要,请考虑以下非常简单的代码:

private static byte[] NetworkToHostOrder (byte[] array, int offset, int length)
{
    return array.Skip (offset).Take (length).Reverse ().ToArray ();
}

int foo = BitConverter.ToInt64 (NetworkToHostOrder (queue, 14, 8), 0);

我正在玩UDP Multicast中的打包数据,因为我注意到包头(Wireshark)中有错误,所以我需要重新排序UInt16八位字节,所以我做了这个:

    private UInt16 swapOctetsUInt16(UInt16 toSwap)
    {
        Int32 tmp = 0;
        tmp = toSwap >> 8;
        tmp = tmp | ((toSwap & 0xff) << 8);
        return (UInt16) tmp;
    }

对于UInt32,

    private UInt32 swapOctetsUInt32(UInt32 toSwap)
    {
        UInt32 tmp = 0;
        tmp = toSwap >> 24;
        tmp = tmp | ((toSwap & 0xff0000) >> 8);
        tmp = tmp | ((toSwap & 0xff00) << 8);
        tmp = tmp | ((toSwap & 0xff) << 24);
        return tmp;
    }

这仅用于测试

    private void testSwap() {
        UInt16 tmp1 = 0x0a0b;
        UInt32 tmp2 = 0x0a0b0c0d;
        SoapHexBinary shb1 = new SoapHexBinary(BitConverter.GetBytes(tmp1));
        SoapHexBinary shb2 = new SoapHexBinary(BitConverter.GetBytes(swapOctetsUInt16(tmp1)));
        Debug.WriteLine("{0}", shb1.ToString());
        Debug.WriteLine("{0}", shb2.ToString());
        SoapHexBinary shb3 = new SoapHexBinary(BitConverter.GetBytes(tmp2));
        SoapHexBinary shb4 = new SoapHexBinary(BitConverter.GetBytes(swapOctetsUInt32(tmp2)));
        Debug.WriteLine("{0}", shb3.ToString());
        Debug.WriteLine("{0}", shb4.ToString());
    }

从哪个输出:

    0B0A: {0}
    0A0B: {0}
    0D0C0B0A: {0}
    0A0B0C0D: {0}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top