Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# UDP-我可以发送两个数据报部分,并使接收端将它们合并为一个吗?_C#_Sockets_Udp_Udpclient - Fatal编程技术网

C# UDP-我可以发送两个数据报部分,并使接收端将它们合并为一个吗?

C# UDP-我可以发送两个数据报部分,并使接收端将它们合并为一个吗?,c#,sockets,udp,udpclient,C#,Sockets,Udp,Udpclient,这可能是一个愚蠢的问题,但由于我对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,

这可能是一个愚蠢的问题,但由于我对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.ImStartingOneBigDatagram();

udpClient.Send(Array1, Array1.Length);
udpClient.Send(Array2, Array2.Length);

udpClient.ThatsAllFolks();
因为如果两者都很大,并且数据速率很高,那么复制会占用很多系统资源。。。 因此,我是否可以告诉udpClient我正在启动UDP分段,然后执行以下操作:

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.ImStartingOneBigDatagram();

udpClient.Send(Array1, Array1.Length);
udpClient.Send(Array2, Array2.Length);

udpClient.ThatsAllFolks();
并确保接收方能够:

byte[] recv = {1,1,1,2,2,2}

为此,我使用C#,我不需要使用
UdpClient
,我只是想说明我的观点。

是的,您可以将任何数据块分成两部分,并将其作为两个单独的UDP数据包发送出去。但是,UDP不保证交付,因此其中一件可能在运输过程中丢失。如果收件人只收到一半的邮件,你会怎么做?很明显,把它扔掉,但要记住UDP

因此,要回答问题的最后一部分“并确保接收方将获得…”,答案是否定的。您使用的是UDP,因此无法确保接收方将获得任何信息


如果为了方便起见而不是为了网络数据包大小的考虑,您希望将发送分成多个数据块,那么您当然可以编写自己的包装器类,它位于UDPclient之上,通过send方法调用接受多个数据块,并且只将所有数据发送到UDPclient.send()当你打电话的时候。那是你包装类的所有人。但这不会减少内存开销,因为包装器必须在大发送之前将数据累积到内存中。此包装器只是为您的客户端代码提供了一种表面上的方便。

使用与Win32 API等效的:

public int-Send(
伊里斯特


但最终这是过早的优化,如果您执行一些测试,您会发现要使用I/O分散-聚集阵列,您至少需要9KB的数据才能提高性能。对于小型缓冲区,即小于a(x86上为4KB)在传递到套接字API之前,您自己构建一个连续缓冲区的速度更快。

使用UDP,您甚至无法确定接收端是否会接收到它们,更不用说它们是否会按顺序接收。数据报要么全部接收,要么根本不接收。接收端不会将多个数据报合并到一个套接字API中单个接收。@Mark H:UDP碎片呢?还有MF(更多碎片)UDP数据包中的标志,如果我可以在第一个数据包中将其设置为1,在最后一个数据包中将其设置为0,这将与UDP pakcet的IP执行碎片相同…不?Cipi,MF标志在IP数据包中,而不是UDP!哦,是的,IP,对不起…我的意思是…我可以从C#设置该标志吗?我看不出“在这种情况下”有任何错误.你有一个发送,一个接收。好的,我愿意冒这个险…但是如何用C#?!如果我通过调用
Send()
2次发送2个数组,接收方必须调用
Receive())
两次获取它们,但我希望它们作为一个数据包到达,我不在乎其中一个是否丢失…:PAFAIK,如果发送两次,则必须接收两次。UDP不会合并。请这样想:当您调用udpclient.send()时,数据会立即放到线路上。当您调用.send()时第二次,第一个UDP消失了,所以第二次发送会发送第二个UDP。好的,正如我所看到的,没有办法做到这一点…IP协议的MF标志如何?它可以“由用户”设置还是网络自动设置…?我想TCP发送()也会有同样的问题,因为语义是被嵌入的。要做你要求的事情,你需要在一个较低的层次上进行操作,在这个层次上,幕后自动为你提供的语义支持较少。我不知道你是否可以从C#开始在这个层次上操作IP堆栈,或者你是否需要切换到其他类似套接字的东西A发送的正是问题的内容,完美的答案。呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜