1

I am testing data transfer using UDP on my computer (localhost). On the sending end, there is a simple while loop that sends packets of 512 bytes. On the receiving end there is a thread that continuously reads form the socket and prints the number of packets it had read so far.

Sending end:

for (int i = 0; i < 5000; i++) {
    byte[] data = new byte[512];
    try {
        client.socket.send(new DatagramPacket(data, 0, data.length, InetAddress.getByName("localhost"), 4337));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Receiving end:

while (true) {
    DatagramPacket packet = new DatagramPacket(input_buffer, input_buffer.length);
    try {
        socket.receive(packet);
        System.out.println("counter = " + l++);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Output:

... 
counter = 1213
counter = 1214
counter = 1215
counter = 1216
counter = 1217

The sender sent 5000 packets, but the receiver received only 1217.

The reason I know the issue lies in the processing speed in the receiving end is that the problem vanishes if I wait a millisecond between sending each packet by adding the line Thread.sleep(1);

Is there any way of solving this problem without adding a delay?

Roy Varon
  • 536
  • 2
  • 5
  • 14
  • 1
    @JanezKuhar Yeah but I am reading the packets as fast as possible, not even inspecting the data inside them or doing any memcpy. It would be very surprising if the socket didn't have some kind of a buffer for cases where two packets arrive at the same time. – Roy Varon Jun 06 '20 at 20:03
  • Taking a closer look at [this answer](https://serverfault.com/a/71412), I think you might be interested in setting a bigger buffer size via [`setReceiveBufferSize()`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/net/DatagramSocket.html#setReceiveBufferSize(int)) and [`setSendBufferSize()`](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/net/DatagramSocket.html#setSendBufferSize(int)). – Janez Kuhar Jun 06 '20 at 22:06
  • I just tried it but unfortunately it did not work (I set the buffer size to 5000*packet_size so there wasn't any shortage of space for sure). – Roy Varon Jun 06 '20 at 22:57
  • I've used `socket.setReceiveBufferSize(Integer.MAX_VALUE);` on the server and it worked. It also worked using: `socket.setReceiveBufferSize(5000*512);`. Perhaps your system is a bit slower. – Janez Kuhar Jun 07 '20 at 00:12
  • Could you please share your code with me? I must have done a mistake somewhere but can't seem to find it. Also, it seems to me like as long as you got enough memory the cpu speed doesn't matter as much. Thank you for helping me with this. – Roy Varon Jun 07 '20 at 00:28
  • 1
    I meant the RAM/cache/DISK speed. Here's my code: https://gist.github.com/Glusk/c93d0b470a0a247aead7e133af00e303 – Janez Kuhar Jun 07 '20 at 00:33
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/215447/discussion-between-janez-kuhar-and-roy-varon). – Janez Kuhar Jun 07 '20 at 00:37
  • 1
    You could speed up the sending too, by not calling `InetAddress.getByName()`every time around the loop. – user207421 Jun 07 '20 at 02:20

1 Answers1

1

Why changing value of SO_RCVBUF doesn't work?

This post shows how to find the maximum receiver buffer size for sockets on linux. In my case the limit was too low therefore some of the packets were discarded.

After further testing, I found that routing the packets through the internet instead of sending them to localhost introduces enough of a delay such that all the packets get to be processed.

Roy Varon
  • 536
  • 2
  • 5
  • 14