0

好吧,据我所知,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接管了。

因此,如果有人可以解释一下,我就是不明白。

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

发送:

                           using (var udpcap = new UdpClient(0))
                           {
                               udpcap.Client.SendBufferSize *= 16;
                               bsize = ms.Length;
                               var buff = new byte[7000];
                               int c = 0;
                               int size = 7000;
                               for (int i = 0; i < ms.Length; i += size)
                               {
                                   c = Math.Min(size, (int)ms.Length - i);
                                   Array.Copy(ms.GetBuffer(), i, buff, 0, c);
                                   udpcap.Send(buff, c, adress.Address.ToString(), 1700);
                               }

收到:

                    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);
                        }
4

2 回答 2

1

您应该使用 TCP。 你写道:发送数据并组装它几乎是不可能的。例如,我有一个 1mb 的图像,我发送它。所以我把它分成 60kb 的文件(或适合包的文件)发送,然后从头到尾一个接一个地发送。......但是,这个理论被打破了,因为没有法律可以告诉包裹它是否可以比另一个更快或更慢地到达,所以只有当你做某种等待计时器时才有可能,并希望最好的到达按照它们发送的顺序。 这正是 TCP 所做的:确保按发送顺序接收数据流的所有片段,没有遗漏、重复或修改。如果你真的想自己重新实现,你应该阅读RFC 793- 它详细讨论了如何在不可靠的数据包服务上构建可靠的数据流。

但实际上,只需使用 TCP。

于 2013-08-19T10:53:19.167 回答
0

您的问题缺少很多有用的细节,但根据所呈现的理解水平,我将尝试以类似的水平回答:

你说得对,一般来说UDP协议根本不保证交付顺序甚至交付。您的本地主机将按照从发送应用程序接收数据包的顺序发送数据包(即请求消息的一部分),然后由网络组件决定如何传递您的请求。然而,在本地网络中(在原始请求者的几跳内),数据包的发送方向并不多。因此,他们很可能只是排成一排,永远不会看到打嗝。

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

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

于 2013-08-18T03:51:46.487 回答