Search code examples
tcpudpwinsockiocp

How to deal with many incoming UDP packets when the server has only 1 UDP socket?


When a server has only 1 UDP socket, and many clients are sending UDP packets to it, what would be the best approach to handle all of the incoming packets?

I think this can also be a problem with TCP packets, since there's a limited thread count, which cannot cover all client TCP socket receive events.

But things are better in this situation because there's 1 TCP socket per client, and even if the network buffer is full, packet receiving is blocked until the queue has space (let me know if I'm wrong).

UDP packets, however, are discarded when the buffer is full, and there's only 1 socket, so the chances of that happening are higher.

How can I solve this problem? I've searched for a while, but I couldn't get a clear answer. Should I implement my own queueing system? Or just maximize the network buffer size?


Solution

  • There is no way to guarantee you won't drop UDP messages. No matter what you do, if the rate of packets being sent is too large, you will drop some, either on the receiving host or somewhere in the network.

    Some things that can help include:

    • Implementing an internal queue for messages in your Java app, and handing them over to a thread pool to process.

    • Increasing the kernel's message buffering.

    But neither of these can deal with the case where the average message arrival rate is higher that the receiver's ability to process them or the network capacity. This will inevitably lead to lost messages (requests).

    I've searched for a while, but I couldn't get a clear answer.

    That is because there isn't one! Some problems are fundamentally unsolvable. For others, the best answer depends on factors that are too hard to measure or predict.

    (If you want certainty ... don't use networking!)


    In the TCP case, what you should do is use a (long-term) socket for each client. Depending on the number of sockets you need to support, you could either:

    • Dedicate a server-side thread to each socket (and client).
    • Use java.nio.channels.Selector and a thread pool.

    You will still get problems if the rate of requests exceeds your server's ability to process them. However, the TCP connections will ensure that requests are not lost, and that the clients get some "back pressure".