我有一个来自套接字连接的大字节[] receiveBuffer,其中包含多个数据包。
我想将单个数据包传递到应用程序中的下一层,但我不想将每个数据包复制到新数组中。
我现在正在做这样的事情
fixed (byte* rxBufferPtr = receiveBuffer)
{
while(more_packets_in_rx_buf)
{
NewPacketReceived(rxBufferPtr + offset, packetSize);
// NewPacketReceived params: NewPacketReceived(byte* packet, int size)
offset += packetSize;
}
}
我想传递托管数组而不是指针和大小,新的NewPacketReceived参数将是:NewPacketReceived(byte [] packet)
我永远不会重复使用接收缓冲区,在它已满后会创建一个新缓冲区。
答案 0 :(得分:3)
不,你不能没有复制。通过偏移或长度是要走的路。你不应该不安全,它并不总是更快。 ArraySegment
结构可以帮助您将偏移量与数组一起传递。
答案 1 :(得分:1)
“byte *仍然是托管内存”?我不明白这个说法。 byte *是指向未知大小的字节数组的指针。相反,托管字节数组具有已知大小。托管字节数组不是内存指针(只要有指针,当指针变为无效时,数据就无法“管理”到另一个内存位置)。根据定义,不是指向未知大小的数组的指针?
请注意,Marshal.Copy性能很差(您应该能够找到样本测试程序,将Marshal.Copy的性能与使用插入收藏搜索引擎名称搜索的其他技术进行比较)。通常使用自己的迭代和赋值来获得更好的复制性能。通过64位(8字节)的块进行分配,因为CPU可以比逐字节复制更快地完成。当字节数组没有填充到8个字节时,最后几个字节将逐字节复制。
再次,AFAIK,没有副本就没有办法从byte *转换为byte [],因此专注于尽可能快地制作不可避免的副本。或者,您可以寻求避免转换的方法。例如,仅在byte []中工作或仅在byte *中工作。 System.Net.Sockets.Socket类在byte []中工作 - 如果你正在使用那个类,你可以坚持使用你的应用程序的byte []吗?