将结构映射到c#中的内存,是否值得?或者,还有更好的方法

时间:2011-06-04 13:57:24

标签: c# pointers struct marshalling unsafe

我正在通过网络发送一些数据包,它们以byte []的形式到达,假设结构是

[int,int,byte,int]

如果这是c ++,我会声明一个struct *并指向byte []。我正在用c#做这个项目,我不确定它是否值得用编组开销,或者如果有更好的方法在c#中处理它,我都是耳朵。

  • 更新,为清晰起见

基本上,他在做什么 Marshaling a Byte array to a C# structure 除了我想知道它是否值得。

4 个答案:

答案 0 :(得分:0)

我认为编组是最好的选择。 可以使用BitConverter自己解析字节数组,但这需要您做更多的工作并且不够灵活。

答案 1 :(得分:0)

这样做的唯一真正原因是将最后一点性能挤出系统。在我看来,你最好用BitConverter来编写它以确保它正常工作。然后,如果获取数据是性能瓶颈,请考虑进行编组。

例如,给定一个结构:

struct MyStruct
{
    private int f1;
    private int f2;
    private byte f3;
    private int f4;
    public MyStruct(int i1, int i2, byte b1, int i4)
    {
        f1 = i1;
        f2 = i2;
        f3 = b1;
        f4 = i4;
    }
    // assume there are public get accessors
}

然后你可以从缓冲区创建一个新的:

var s = new MyStruct(BitConverter.ToInt32(buff, 0),
    BitConverter.ToInt32(buff, 4),
    BitConverter.ToUInt8(buff, 8),
    BitConverter.ToInt32(buff, 9));

编写和验证比编组更容易,并且可能足够快以满足您的需求。

答案 2 :(得分:0)

嗯,我想每个人都有自己喜欢的方式。当以任何OO语言在字节流上接收协议单元时,我通常通过调用其'bool addByte()方法将每个接收到的字节触发到'ProtocolUnit'类实例中。类中的状态机处理字节,错误/健全性检查汇编的字段。如果已完整地接收到ProtocolUnit,则addByte()方法函数返回true以向调用者指示PDU已正确组装。通常,然后将实例排队到将要处理它的任何内容和创建的新ProtocolUnit(或depooled),以便它可以开始组装下一个PDU。

隐含的是,可以识别消息的开始,以便在出现错误时,状态机可以自行重置,从而转储错误的数据,或者将“true”返回到addByte()调用,设置一个合适的errorMessage,调用者可以检查该决定做什么,(例如,如果errorMess属性是“”,那么队列到handler else队列到错误记录器)。

我确信你认为这是一个巨大的矫枉过正,但它对我有用:)

RGDS, 马丁

PS尝试避免在开始时传输长度的协议,这是识别消息开始/结束的唯一方法。这非常脆弱,容易爆炸,尤其是UDP等非安全传输。即使使用TCP,我也知道一个x **** x路由器偶尔会为数据包添加一个空...

答案 3 :(得分:0)

作为BitConverter的替代方法,请将byte[]中的每个MemoryStream换行,并使用BinaryReader提取字段。类似,但是流为你保留了抵消。