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

我正在尝试将两个字节转换为无符号短路,以便我可以检索实际的服务器端口值。 我基于回复格式从协议规范开始 。 我尝试使用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。

我这样做是错误的吗?

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

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

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

BitConverter正在做正确的事情,你只需要低字节和高字节混合 – 你可以手动使用bitshift进行validation:

 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 

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

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