0

I am trying to find the best way to write a multi-threaded server in C# (running on a Windows system) capable of handling a big amount of UPD packets per second. Here are the main assumptions:

-I have hundreds of clients sending small unicast UDP packets to the server on a specific port at a very high rate.

-The network can handle the load and the NIC is fast enough to send the packets to the OS.

-Packets are independent. They can be treated separately.

-My program has to read the UPD stream as fast as possible, so that no packets are lost because of an overflow.

-One thread cannot read and process the packets as fast as the NIC receives them. The load has to be spread across all several threads.

This article https://blog.cloudflare.com/how-to-receive-a-million-packets/ explains that receiving packets from several threads (in a naive way) is not the right approach as they will waste time fighting for a lock on the UDP receive buffer. This is why Windows added the SO_REUSEADDR and SO_EXCLUSIVEADDRUSE options which allows different sockets to bind to a port already used by another socket. According to the same article, the SO_REUSEPORT option on a Unix system allows the load to be evenly spread across several processes which will own a dedicated UDP receiver buffer. The dream for multithreaded UDP reception! Someone said here SO_REUSEADDR and UDP behavior in Windows that on Windows, multicast packets will be multiplexed across the sockets while unicast packets will only be sent to the first open socket (which means only one sockets will receive all the packets?).

My question is, does Windows evenly spread the unicast load across the different sockets bound to the same port with the SO_REUSEADDR option (if so, is it with a Round-robin system or maybe a hash function)? Is it the right way of parallelizing efficiently high-speed UDP reception?

If not, would it be better to shift the load "switch" point upstream by making the clients send to different ports (which will be read by independent sockets in separate threads on the server side)?

Thanks in advance

Community
  • 1
  • 1
Alex
  • 31
  • 3
  • 1
    The distribution behavior of multiple sockets bound to the same IP/Port is not documented. All that is known is that only one socket will receive a unicast packet, but you won't know which socket. For what you are attempting, you should consider using Overlapped I/O or I/O Completion Ports instead, using multiple threads to service the I/O responses. When a packet is received, a thread will be woken to handle it. Have that thread process the packet (or queue it off somewhere for parallel processing) and then immediately issue a new read. You can have multiple reads "in progress". – Remy Lebeau Aug 04 '16 at 17:58
  • Thanks @RemyLebeau, I've seen a couple of people talking about IOCP in UDP related questions. I wasn't sure if it was the right way to go for this kind of problem. I will have a deeper look into this. – Alex Aug 05 '16 at 10:53

0 Answers0