Search code examples
network-programmingudpasio

UDP: How make the data flow rate smooth for UDP packets over a network connection


Scenario:
Using Boost Asio 1.69 I have a C++ server running on Linux Fedora 4.9 and a client running on an Android 10 phone using a peer to peer connection. There is continuous sending of data from server to client and occasionally a packet from client to server.

Problem:
Things work well but due to my Server sending many packets at a high rate, my client is unable to catch up. This causes packets to get dropped. Digging deep and reading about the problem, I learnt that there is something called UDP packets pacing. Another link here. This seems to me as a potential solution to my problem. At least something I want to try to avoid the burst of flow of UDP packets and rather try smoothen the flow.

So I tried the following firstly:

uint32_t bytes_per_second = 1000000;
if(setsockopt(udp_socket, SOL_SOCKET, SO_MAX_PACING_RATE, &bytes_per_second, sizeof(bytes_per_second)) < 0) {
    std::cout << "Unable to set socket max pacing rate" << std::endl;
}

But above does not seem to have any affect. I different numbers set for bytes_per_second with no helpful effect and the problem stayed the same.

Question:
How can I effectively exercise UDP packets pacing? Or how can I ensure a slight gap between the packets I am sending from my Linux server side?

Is it a linux configuration I could do or is it something I could do by calling setsockopt on the udp socket? Any suggestions towards potential investigations are also welcome!


Solution

  • What you're describing is a Flow Control problem. The problem in flow control is not how to pace the rate of packets, but how to determine the right rate in the first place. You've set bytes_per_second = 1000000;, but why? Why not half that rate? Why not one tenth? Perhaps you're not seeing any improvement because the rate is still too high.

    Your protocol needs some way of finding an appropriate rate for a specific client. This can only be done using information from the client. For instance you could add sequence numbers to the packets and have the client report its last processed sequence number. If that number is too old then you need to slow down.

    TCP has a built-in flow control mechanism in which the client reports the amount of free space it has in the receive buffer. This information is reported in every TCP segment, so the sender always knows how much additional data it can send. Perhaps it's worth considering switching to TCP for your application?