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

时间:2011-04-21 21:07:24

标签: c# arrays byte short

我正在尝试将两个字节转换为unsigned short,以便我可以检索实际的服务器端口值。我根据回复格式将其从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&amp; 135,转换后的预期端口值应为27015,但使用BitConverter得到的值为34665。

我做错了吗?

3 个答案:

答案 0 :(得分:28)

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

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

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

答案 1 :(得分:8)

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

答案 2 :(得分:7)

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

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);