UDP – 我可以发送两个数据报部分,并使接收端将它们组合成一个吗?
这可能是一个愚蠢的问题,但由于我对UDP相对较新,所以…如果我有两个独立的字节数组,我需要接收端作为一个大数组,例如:
byte[] Array1 = {1,1,1} byte[] Array2 = {2,2,2}
我可以避免创建缓冲区并将每个数组复制到其中,然后发送该缓冲区,如下所示:
byte[] Buffer= new byte[Array1.Length + Array2.Length]; Buffer.BlockCopy(Array1, 0, Buffer, 0, Array1.Length); Buffer.BlockCopy(Array2, 0, Buffer, Array1.Length, Array2.Length); udpClient.Send(Buffer, Buffer.Length);
因为如果两者都很大,并且数据速率很高,那么复制会占用很多系统资源……所以我可以告诉udpClient我正在启动UDP碎片,然后这样做:
udpClient.ImStartingOneBigDatagram(); udpClient.Send(Array1, Array1.Length); udpClient.Send(Array2, Array2.Length); udpClient.ThatsAllFolks();
并确保接收方获得:
byte[] recv = {1,1,1,2,2,2}
我正在使用C#,我不需要使用UdpClient
,我只是在说明我的观点。
使用相当于Win32 API的WSASendMsg
:
public int Send( IList> buffers, SocketFlags socketFlags, out SocketError errorCode )
http://msdn.microsoft.com/en-us/library/ms145161.aspx
但最终这是过早优化,如果您执行某些测试,您将看到使用I / O分散收集数组,您需要至少9KB的数据才能获得性能提升。 对于小缓冲区,即小于页面大小 (x86上为4KB),在传递给套接字API之前自己构建连续缓冲区会更快。
是的,您可以将任何数据块拆分为两部分,并将其作为两个单独的UDP数据包发送出去。 但是,UDP不保证传送,因此其中一个部分可能在传输过程中丢失。 如果收件人只收到一半邮件,你会怎么做? 显然,扔掉它,但要记住UDP的一些事项。
所以,回答问题的最后一部分“并确保接收方会得到……”答案是否定的。 你正在使用UDP,所以你不能确定接收方会得到任何东西。
如果您希望将发送分解为多个块以方便使用而不是网络数据包大小问题,那么您当然可以编写自己的封装类,它位于UDP客户端之上,并通过Send方法调用接受多个数据块,并且只发送当您在包装器类上调用.ThatsAllFolks时,所有数据到udpclient.Send()。 但这并不会减少内存开销,因为包装器必须在Big Send之前在内存中累积数据。 这个包装器只是为您的客户端代码提供便利。