【问题标题】:How can one simplify network byte-order conversion from a BinaryReader?如何从 BinaryReader 简化网络字节顺序转换?
【发布时间】:2008-09-23 21:13:55
【问题描述】:

System.IO.BinaryReader 以 little-endian 格式读取值。

我有一个 C# 应用程序连接到服务器端的专有网络库。正如人们所期望的那样,服务器端以网络字节顺序发送所有内容,但我发现在客户端处理这一点很尴尬,尤其是对于无符号值。

UInt32 length = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32());

是我想出的从流中获取正确无符号值的唯一方法,但这看起来既尴尬又丑陋,我还没有测试这是否会剪掉高阶值所以我必须做一些有趣的 BitConverter 的事情。

我是否缺少某种方法,而不是为整个事物编写一个包装器以避免每次读取时出现这些丑陋的转换?似乎读者应该有一个字节序选项来使这样的事情变得更简单,但我没有遇到任何事情。

【问题讨论】:

  • 它现在无济于事,但我为 BinaryReder/Writer 创建了一个 connect ticket 以支持 Bigendian。去投票here
  • 当字节可以表示本机整数时,原始代码是否正常工作?
  • @Denise Skidmore - 是的,确实如此。请参阅 .net 源代码。

标签: c# .net networking


【解决方案1】:

没有内置转换器。这是我的包装(如您所见,我只实现了我需要的功能,但结构很容易根据您的喜好更改):

/// <summary>
/// Utilities for reading big-endian files
/// </summary>
public class BigEndianReader
{
    public BigEndianReader(BinaryReader baseReader)
    {
        mBaseReader = baseReader;
    }

    public short ReadInt16()
    {
        return BitConverter.ToInt16(ReadBigEndianBytes(2), 0);
    }

    public ushort ReadUInt16()
    {
        return BitConverter.ToUInt16(ReadBigEndianBytes(2), 0);
    }

    public uint ReadUInt32()
    {
        return BitConverter.ToUInt32(ReadBigEndianBytes(4), 0);
    }

    public byte[] ReadBigEndianBytes(int count)
    {
        byte[] bytes = new byte[count];
        for (int i = count - 1; i >= 0; i--)
            bytes[i] = mBaseReader.ReadByte();

        return bytes;
    }

    public byte[] ReadBytes(int count)
    {
        return mBaseReader.ReadBytes(count);
    }

    public void Close()
    {
        mBaseReader.Close();
    }

    public Stream BaseStream
    {
        get { return mBaseReader.BaseStream;  }
    }

    private BinaryReader mBaseReader;
}

基本上,ReadBigEndianBytes 完成了繁重的工作,并将其传递给 BitConverter。如果您读取大量字节,肯定会出现问题,因为这会导致大量内存分配。

【讨论】:

  • 注意:Array.Reverse() 将反转您的数组的顺序。
  • 读取单个字节可能很慢。最好一次读取尽可能多的字节。此外,使用传统的位转换解决方案,字节序转换速度最快。当然,对于少量数据来说没什么大不了的。
【解决方案2】:

我构建了一个自定义 BinaryReader 来处理所有这些。它的地址为part of my Nextem library。它还有一种定义二进制结构的非常简单的方法,我认为这对你有帮助——查看示例。

注意:目前仅在 SVN 中,但非常稳定。如果您有任何问题,请发送电子邮件至 cody_dot_brocious_at_gmail_dot_com。

【讨论】:

  • 谢谢。我有点希望避免获得额外的库依赖项,因为整个事情确实应该相当小且简单,但我会记住这一点。不过,很高兴看到许可证是明确的。 :)
  • 啊,我明白了。好吧,如果您选择使用它,我希望它对您有用。是的,出于这个原因,我进入了公共领域——我希望人们能够用它做任何他们想做的事情,并且组件足够小,不需要担心找回补丁 :)
猜你喜欢
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 2012-05-23
相关资源
最近更新 更多