我试图将两个字节转换为无符号短,以便我可以检索实际的服务器端口值。我是基于这个协议规范下的回复格式。我尝试使用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);
在小端架构中,低序字节需要在数组中排在第二位。正如lasseespeholt在评论中指出的那样,您需要在大端架构上颠倒顺序。这可以用BitConverter检查。IsLittleEndian财产。或者使用IPAddress可能是一个更好的解决方案。HostToNetworkOrder(首先转换值,然后调用该方法将字节按正确的顺序排列,而不管端序如何)
BitConverter正在做正确的事情,你只是有低字节和高字节混合-你可以使用位移手动验证:
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);