C# UDP发送数据,这是我不知道的´;我不太明白

C# UDP发送数据,这是我不知道的´;我不太明白,c#,udp,C#,Udp,据我所知,UDP的工作原理如下: 你有你想要发送的数据,你对UDP客户端说,嘿,发送这个数据 然后UDP客户端会说“确定为什么不”,并将数据发送到选定的IP和端口 如果它通过或以正确的顺序是另一个故事,它已经发送了数据,你没有要求任何其他东西 现在从这个角度来看,发送数据并组装数据几乎是不可能的。 例如,我有一个1mb的图像,我发送它 所以我把它分成60kb的文件(或者适合软件包的文件),然后从头到尾一个接一个地发送 所以从理论上讲,如果把所有的都加上,图像应该是完全相同的 但是,这一理论是错误

据我所知,UDP的工作原理如下:

你有你想要发送的数据,你对UDP客户端说,嘿,发送这个数据

然后UDP客户端会说“确定为什么不”,并将数据发送到选定的IP和端口

如果它通过或以正确的顺序是另一个故事,它已经发送了数据,你没有要求任何其他东西

现在从这个角度来看,发送数据并组装数据几乎是不可能的。 例如,我有一个1mb的图像,我发送它

所以我把它分成60kb的文件(或者适合软件包的文件),然后从头到尾一个接一个地发送

所以从理论上讲,如果把所有的都加上,图像应该是完全相同的

但是,这一理论是错误的,因为没有法律规定包裹的到达速度是快还是慢,所以只有在你设置了某种等待计时器,并希望包裹能按发送顺序到达的情况下,这一理论才有可能实现

不管怎样,我想了解的是,为什么会这样:

   void Sending(object sender, NAudio.Wave.WaveInEventArgs e)
    {
        if (connect == true && MuteMic.Checked == false)
        {
            udpSend.Send(e.Buffer, e.BytesRecorded, otherPartyIP.Address.ToString(), 1500);
        }
    }
接收:

        while (connect == true)
        {
            byte[] byteData = udpReceive.Receive(ref remoteEP);
            waveProvider.AddSamples(byteData, 0, byteData.Length);
        }
这基本上就是,它通过udp发送音频缓冲区

接收PAR只添加在缓冲区中接收的UDP数据并播放它。 现在,这是可行的

我想知道。。为什么?

这是如何工作的,数据是如何以正确的顺序发送和添加的,从而显示为一个恒定的音频流

因为如果我用一张图片来解释,我可能会得到所有的数据

但它们可能是随机排列的,我只能通过标记包裹之类的东西来解决这个问题。然后就没有理由了,TCP接管了

所以如果有人能解释一下,我就是不明白

下面是一个发送图像时的代码示例,它可以正常工作。但是当整个字节数组没有发送时,它似乎工作得更好,这意味着图像的某些部分已损坏(不确定原因,可能与字节数组的大小有关)

发送:

使用(var udpcap=new UdpClient(0))
{
udpcap.Client.SendBufferSize*=16;
b尺寸=毫秒长度;
var buff=新字节[7000];
int c=0;
int size=7000;
对于(int i=0;i
收到:

                    using (var udpcap = new UdpClient(1700))
                    {
                        udpcap.Client.SendBufferSize *= 16;
                        var databyte = new byte[1619200];

                        int i = 0;
                        for (int q = 0; q < 11; ++q)
                        {
                            byte[] data = udpcap.Receive(ref adress);
                            Array.Copy(data, 0, databyte, i, data.Length);
                            i += data.Length;
                        }
                        var newImage = Image.FromStream(new MemoryStream(databyte));
                         gmp.DrawImage(newImage,0,0);
                        }
使用(var udpcap=new UdpClient(1700))
{
udpcap.Client.SendBufferSize*=16;
var databyte=新字节[1619200];
int i=0;
对于(int q=0;q<11;++q)
{
字节[]数据=udpcap.Receive(参考地址);
复制(数据,0,数据字节,i,数据.Length);
i+=数据长度;
}
var newImage=Image.FromStream(新内存流(数据字节));
gmp.DrawImage(newImage,0,0);
}

您的问题中遗漏了很多有用的细节,但基于所提供的理解水平,我将尝试以类似的水平回答:

您完全正确,通常UDP协议根本不能保证传递顺序,甚至根本不能保证传递。您的本地主机将发送数据包(即请求消息的一部分)按照它从发送应用程序接收请求的顺序,从发送应用程序到网络组件决定如何发送请求对于这些数据包来说,并没有太多的方向可供选择。因此,它们很可能只是排成一行,永远不会出现打嗝的情况

然而,在更大的互联网上,在您的请求主机和目标之间的每个路由器可能有多种路由选择。沿途的每个路由器都可以选择消息的哪个方向。假设所有路径都是相等的(它们不是)两台主机之间的每个网段都有保证的可靠性,可能会看到与网络内类似的结果(增加延迟)。不幸的是,这两种情况都不可靠(互联网上的不同路径根据客户机和服务器的不同表现不同,互联网上的任何一条路径都不应该被认为是可靠的(这就是为什么它是一个“网络”)


这些当然是基于我自己在网络支持和管理角色方面的经验得出的一般性结论。其他StackExchange站点的成员可能能够提供更好的反馈。

您应该使用TCP。您写道:发送数据和组装数据几乎是不可能的。例如,我有一个1mb的映像,我使用了所以我把它分成60kb的文件(或者一些适合包的文件),然后从第一个发送到最后一个……但是,这一理论被打破了,因为没有规律告诉包是否可以比另一个更快或更慢地到达,所以只有当你做了某种等待计时器,并希望最好的结果是按照发送的顺序到达时,这才有可能实现。这正是TCP所做的:确保所有的pi数据流的ECE是按照发送顺序接收的,没有遗漏、重复或修改。如果你真的想自己重新实现,你应该阅读-它详细介绍了如何构建可靠的数据流
                    using (var udpcap = new UdpClient(1700))
                    {
                        udpcap.Client.SendBufferSize *= 16;
                        var databyte = new byte[1619200];

                        int i = 0;
                        for (int q = 0; q < 11; ++q)
                        {
                            byte[] data = udpcap.Receive(ref adress);
                            Array.Copy(data, 0, databyte, i, data.Length);
                            i += data.Length;
                        }
                        var newImage = Image.FromStream(new MemoryStream(databyte));
                         gmp.DrawImage(newImage,0,0);
                        }