【问题标题】:C# - Could sending 5 Multicast UDP packets result in 3 or more being lostC# - 发送 5 个多播 UDP 数据包可能导致 3 个或更多丢失
【发布时间】:2016-04-16 06:55:18
【问题描述】:

大家好

是否有可能通过 LAN 发送多播数据包导致部分或至少 50% 的数据包丢失。

我的应用程序使用多播数据包,在发送这些数据包时,有时我只收到 1 个,其他时候 2 个。我只收到了 2 次我发送的所有数据包。

这是我为查看返回/接收哪些数据包所做的测试。发送了 5 个数据包,但并非全部返回(F - 发送数据包序列中的最终数据包)

2000 个随机字符用于这些测试。

12345 14F

12345 134F

12345 1F

12345 1

12345 1

12345 1F

12345 134F

我总是至少收到 1 个数据包。我理解 Multicast = UDP,但是丢了这么多包似乎不太正常。

发送多播数据包:

        Socket _listener_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        foreach (IPAddress localIP in Dns.GetHostAddresses(Dns.GetHostName()).Where(i => i.AddressFamily == AddressFamily.InterNetwork))
        {                
            _listener_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(_MultiIP, localIP));
            _listener_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 1);
            _listener_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            _listener_socket.MulticastLoopback = true;
            _listener_socket.Connect(new IPEndPoint(_MultiIP, _PORT));
            int count = MSGS_TO_SEND.Count;
            while (count > 0)
            {                    
                count--;
                byte[] temp = (byte[])(MSGS_TO_SEND.Dequeue());
                _listener_socket.Send(temp, _BYTE_BUFFER_SIZE, SocketFlags.None);
                MSGS_TO_SEND.Enqueue(temp);
            }
        }
        _listener_socket.Close();

并接收:

        Socket _sender_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        IPEndPoint ipep = new IPEndPoint(IPAddress.Any, _PORT);
        _sender_socket.Bind(ipep);
        IPAddress localip = _MultiIP;
        _sender_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(localip, IPAddress.Any));
        Q_RECIEVE = new Queue<char[]>();
        while (_sender_socket.IsBound && !bStop)
        {
            byte[] b = new byte[_BYTE_BUFFER_SIZE];
            _sender_socket.Receive(b);
            char[] chars = new char[_BYTE_BUFFER_SIZE];
            System.Buffer.BlockCopy(b, 0, chars, 0, b.Length);
            Q_RECIEVE.Enqueue(chars);
        }

更新

一些有趣的结果 - Kudo 向 Seth 提出建议

在测试了防火墙建议后,我得到了一些改进,但仍然有丢包:

我禁用了卡巴斯基防火墙,默认恢复为 Windows 10 Defender 防火墙:

12345 234F

12345 234F

12345 1234F

12345 1F

12345 14F

12345 234F

12345 1

12345 1

12345 234F

禁用卡巴斯基防火墙后,我将 byte[] 大小从 1024 更改为 512,因此每个数据包仅发送 256 个字符(线程休眠时间为 20 毫秒),结果显着改善:

123456789 2345678F

123456789 2345678F

123456789 2345678F

123456789 2345678F

123456789 2345678F

只有我的第一个数据包被丢弃,但这是一个很大的进步!

【问题讨论】:

  • 环境因素会导致UDP丢包,如低RSSI(低信噪比)。
  • 是的,有可能,虽然可能性不大,但可能涉及一些程序员的错误。
  • @tinky_winky 需要详细说明,程序员的错误 - 这是否指的是我的代码中的错误,因为这是改编自多播教程 :p 但是这个程序员的一般错误,我认为这也指大量应用程序发送 1000 个 udp 数据包,在我的情况下,5 个数据包中有 3 个不返回......这似乎不正常
  • 我真的很想帮助你,但是技术已经变成了 C#,谢天谢地我不太了解。
  • @tinky_winky 对于任何误解我深表歉意,我想我需要更改一个标签左右。这是我引用和编码的 C#。

标签: c# sockets networking network-programming udp


【解决方案1】:

是的,无论何时发送 UDP,都会有多种因素导致数据包丢失,即使在 LAN 上也是如此。以下是一些似乎相关的内容:

  • 2000 字节大于 1500 的典型 LAN MTU(更少标头)。这意味着数据报将被分段。如果任何片段丢失,则整个数据报都会丢失,如果片段以特定模式到达,某些防火墙会阻止它们。
  • UDP 本身没有流量控制。如果您发送太多数据,太快,数据包将被丢弃。听起来您一次只发送几个数据报,但请检查您的 UDP 发送和接收缓冲区。如果其中一个仅大到足以容纳一两个数据报,那么其余的可能会被丢弃。
  • 防火墙有时会奇怪地对待 UDP。 DoS 预防、深度数据包检测、隧道阻塞和一堆听起来很安全的流行语意味着防火墙对数据报的用途进行了疯狂的猜测。如果防火墙猜错了,您的一些数据报可能会被丢弃。
  • 您似乎将 TTL 设置为 1。理论上,这对于 LAN 是正确的。但如果本地路由有点偏离,可能会导致一些数据包被丢弃。

因此,将您的有效负载减少到 1400 字节,确保您的 UDP 发送和接收缓冲区至少为 64 KB(最好是 1 兆字节,没有理由小气),禁用任何防火墙,并使用更大的 TTL 进行测试。

如果有任何解决问题的方法,您可以深入查找确切原因。

【讨论】:

  • @SethNoble 感谢您提供深入的信息。 1. 我的 byte[] 缓冲区长度为 1024B 或 1 Kb。(字符串长度 = 512 * sizeof(char) = 1024)。 2. 我尝试让“发送线程”休眠 20 毫秒,但没有帮助。 3. 防火墙 - 查看更新。 4. 我有一个家庭路由器,我在上面进行测试,我尝试了 TTl 为 2,Wireshark 报告了格式错误的数据包
  • 到目前为止应该足够慢且足够小。尝试使用单播进行测试:可能是您的网络中的某些东西以不同的方式处理多播。一些防火墙和设备确实会限制它。检查您的交换机是否适合多播。您也可以尝试单播到 LAN 子网的广播地址。例如,192.168.255.255。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-04
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
相关资源
最近更新 更多