CybeX
CybeX

Reputation: 2396

C# - Could sending 5 Multicast UDP packets result in 3 or more being lost

Good Day All

Is it possible sending multicast packet(s) over a LAN result in some or at least 50% of the packets being lost.

My application makes use of Multicast packets, when sending these packets, at times I only receive 1, other times 2. Only 2 times I received all the packets I sent.

Here are tests I did to see which packets are returned/received. 5 packets were sent, not all are returned (F - Final packet in sequence of packets sent)

2000 Random chars were used for these tests.

12345 14F

12345 134F

12345 1F

12345 1

12345 1

12345 1F

12345 134F

I always recieve atleast 1 packet. I understand Multicast = UDP, but it does not seem normal to lose so many packets.

sending multicast packets:

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

and recieving:

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

UPDATE

Some interesting results - Kudo's to Seth for his suggestions

After testing the firewall suggestion, I received some improvement but still having packet loss:

I disabled my Kaspersky firewall, defauting back to Windows 10 Defender Firewall:

12345 234F

12345 234F

12345 1234F

12345 1F

12345 14F

12345 234F

12345 1

12345 1

12345 234F

With Kaspersky Firewall disabled, I changed the byte[] size from 1024 to 512 thus only sending 256 char's per packet (and thread sleep time of 20ms), results improved drastically:

123456789 2345678F

123456789 2345678F

123456789 2345678F

123456789 2345678F

123456789 2345678F

Only my first packet was being dropped, but this is quite an improvement!

Upvotes: 1

Views: 705

Answers (1)

Seth Noble
Seth Noble

Reputation: 3303

Yes, any time you are sending UDP there are a variety of factors which can cause packets to be lost, even on a LAN. Here are a few that seem relevant:

  • 2000 bytes is larger than the typical LAN MTU of 1500 (less headers). That means the datagram will be fragmented. If any fragment is lost, the entire datagram is lost, and some firewalls will block fragments if they arrive in certain patterns.
  • UDP itself has no flow control. If you send too much data, too quickly, packets will be dropped. It sounds like you are only sending a few datagrams at a time, but check your UDP send and receive buffers. If either is only big enough to hold one or two datagrams, then the rest may be dropped.
  • Firewalls sometimes treat UDP strangely. DoS prevention, deep packet inspection, tunnel blocking, and a bunch of security sounding buzzwords mean the firewall making a wild guess about the purpose of a datagram. If the firewall guesses incorrectly, some of your datagrams may be dropped.
  • It looks like you are setting TTL to 1. In theory, that's correct for a LAN. But if the local routing is a bit off, that could cause some packets to be dropped.

So, reduce your payload to 1400 bytes, make sure your UDP send and receive buffers are at least 64 kilobytes (preferably a megabyte, there's no reason to be stingy), disable any firewalls, and test with a larger TTL.

If any of that fixes the problem, you can dig in to find the exact cause.

Upvotes: 3

Related Questions