在 C# 中将 2 个字节转换为 Short

Posted

技术标签:

【中文标题】在 C# 中将 2 个字节转换为 Short【英文标题】:Converting 2 bytes to Short in C# 【发布时间】:2011-08-10 14:59:53 【问题描述】:

我正在尝试将两个字节转换为无符号短字节,以便检索实际的服务器端口值。我基于回复格式下的protocol specification。我尝试为此使用BitConverter.ToUint16(),但问题是,它似乎没有抛出预期值。请参阅下面的示例实现:

int bytesRead = 0;

while (bytesRead < ms.Length)

    int first = ms.ReadByte() & 0xFF;
    int second = ms.ReadByte() & 0xFF;
    int third = ms.ReadByte() & 0xFF;
    int fourth = ms.ReadByte() & 0xFF;
    int port1 = ms.ReadByte();
    int port2 = ms.ReadByte();
    int actualPort = BitConverter.ToUInt16(new byte[2] (byte)port1 , (byte)port2 , 0);
    string ip = String.Format("0.1.2.3:4-5 = 6", first, second, third, fourth, port1, port2, actualPort);
    Debug.WriteLine(ip);
    bytesRead += 6;

给定一个示例数据,假设对于两个字节值,我有 105 和 135,转换后的预期端口值应该是 27015,但我使用 BitConverter 得到的值是 34665。

我做错了吗?

【问题讨论】:

【参考方案1】:

如果您反转 BitConverter 调用中的值,您应该会得到预期的结果:

int actualPort = BitConverter.ToUInt16(new byte[2] (byte)port2 , (byte)port1 , 0);

在 little-endian 架构上,低位字节需要在数组中排在第二位。正如 lasseespeholt 在 cmets 中指出的那样,您需要在大端架构上颠倒顺序。这可以通过BitConverter.IsLittleEndian 属性进行检查。或者使用IPAddress.HostToNetworkOrder 可能是一个更好的整体解决方案(首先转换值,然后调用该方法以正确的顺序放置字节,而不管字节顺序如何)。

【讨论】:

如果应用程序在不同的架构上运行,您确定这会起作用吗? @lasseespeholt:这是一个很好的观点。它可能确实需要使用IsLittleEndian 进行检查。对于大端架构,顺序需要在 OP 中给出。 来自@BrokenGlass 的解决方案 ushort value2 = (ushort)(port1 + (port2 【参考方案2】:

BitConverter 正在做正确的事情,您只是混淆了低字节和高字节 - 您可以手动使用 bitshift 进行验证:

byte port1 = 105;
byte port2 = 135;

ushort value = BitConverter.ToUInt16(new byte[2]  (byte)port1, (byte)port2 , 0);
ushort value2 = (ushort)(port1 + (port2 << 8)); //same output

【讨论】:

+1 表示“手动”方法。在我看来,BitConverter 确实可以进行许多检查和字节序检查,这可能会破坏代码。 来自您的解决方案: ushort value2 = (ushort)(port1 + (port2 【参考方案3】:

要同时处理小端和大端架构,您必须执行以下操作:

if (BitConverter.IsLittleEndian)
    actualPort = BitConverter.ToUInt16(new byte[2] (byte)port2 , (byte)port1 , 0);
else
    actualPort = BitConverter.ToUInt16(new byte[2] (byte)port1 , (byte)port2 , 0);

【讨论】:

以上是关于在 C# 中将 2 个字节转换为 Short的主要内容,如果未能解决你的问题,请参考以下文章

如何在飞镖中将 2 个字节转换为 Int16?

在 JavaCard 中将字节转换为短字节

在 C# 中将 3 个字节转换为有符号整数

在python中将bytearray转换为short int

在c#中将字符串转换为字节数组

如何在 C# 中将字节 [] 转换为日期时间?