如何从BinaryReader简化网络字节顺序转换?

时间:2008-09-23 21:13:56

标签: c# .net networking

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

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

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

是我提出从流中获取正确的无符号值的唯一方法,但这似乎既笨拙又丑陋,我还没有测试是否只会削减高阶值我必须做有趣的BitConverter。

我是否有某种方法可以避免在整个过程中编写一个包装器以避免每次读取时出现这些丑陋的转换?似乎读者应该有一个endian-ness选项来使这样的事情变得更简单,但我没有遇到过任何事情。

2 个答案:

答案 0 :(得分:5)

没有内置转换器。这是我的包装器(你可以看到,我只实现了我需要的功能,但结构很容易根据你的喜好改变):

/// <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。如果你读取大量的字节会有一个明确的问题,因为这会导致大量的内存分配。

答案 1 :(得分:1)

我构建了一个自定义BinaryReader来处理所有这些。它以part of my Nextem library的形式提供。它还有一种非常简单的方法来定义二进制结构,我认为这将对您有所帮助 - 请查看示例。

注意:它现在只在SVN中使用,但非常稳定。如果您有任何疑问,请发送电子邮件至cody_dot_brocious_at_gmail_dot_com。

相关问题