Mat*_*vis 13 .net c# networking bytearray .net-3.5
我有一个字节数组,代表一个完整的TCP/IP数据包.为了澄清,字节数组的排序如下:
(IP标头 - 20字节)(TCP标头 - 20字节)(有效负载 - X字节)
我有一个Parse接受字节数组并返回一个TCPHeader对象的函数.它看起来像这样:
TCPHeader Parse( byte[] buffer );
Run Code Online (Sandbox Code Playgroud)
给定原始字节数组,这是我现在调用此函数的方式.
byte[] tcpbuffer = new byte[ 20 ];
System.Buffer.BlockCopy( packet, 20, tcpbuffer, 0, 20 );
TCPHeader tcp = Parse( tcpbuffer );
Run Code Online (Sandbox Code Playgroud)
有没有一种方便的方法可以将TCP字节数组(即完整TCP/IP数据包的字节20-39)传递给Parse函数,而无需先将其提取到新的字节数组?
在C++中,我可以执行以下操作:
TCPHeader tcp = Parse( &packet[ 20 ] );
Run Code Online (Sandbox Code Playgroud)
C#中有类似的东西吗?我想尽可能避免临时字节数组的创建和后续垃圾收集.
Spo*_*odi 24
您可以在.NET框架中看到并且我建议在此处使用的常见做法是指定偏移量和长度.因此,使您的Parse函数也接受传递的数组中的偏移量,以及要使用的元素数.
当然,同样的规则也适用于传递类似C++的指针 - 不应修改数组,否则如果您不确定何时将使用数据,则可能导致未定义的行为.但是,如果您不再修改数组,这没有问题.
cas*_*One 22
ArraySegment<byte>在这种情况下我会通过.
您可以将Parse方法更改为:
// Changed TCPHeader to TcpHeader to adhere to public naming conventions.
TcpHeader Parse(ArraySegment<byte> buffer)
Run Code Online (Sandbox Code Playgroud)
然后你会改变对此的调用:
// Create the array segment.
ArraySegment<byte> seg = new ArraySegment<byte>(packet, 20, 20);
// Call parse.
TcpHeader header = Parse(seg);
Run Code Online (Sandbox Code Playgroud)
使用ArraySegment<T>不会复制数组,它将在构造函数中为您进行边界检查(这样就不会指定不正确的边界).然后你改变你的Parse方法来使用段中指定的边界,你应该没问题.
您甚至可以创建一个方便的重载,它将接受完整的字节数组:
// Accepts full array.
TcpHeader Parse(byte[] buffer)
{
// Call the overload.
return Parse(new ArraySegment<byte>(buffer));
}
// Changed TCPHeader to TcpHeader to adhere to public naming conventions.
TcpHeader Parse(ArraySegment<byte> buffer)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
40610 次 |
| 最近记录: |