我正在通过网络发送一些数据包,它们以byte []的形式到达,假设结构是
[int,int,byte,int]
如果这是c ++,我会声明一个struct *并指向byte []。我正在用c#做这个项目,我不确定它是否值得用编组开销,或者如果有更好的方法在c#中处理它,我都是耳朵。
基本上,他在做什么 Marshaling a Byte array to a C# structure 除了我想知道它是否值得。
答案 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
提取字段。类似,但是流为你保留了抵消。