Home > Enterprise >  Why does socat UDP-RECVFROM terminate after exactly 1861 datagrams?
Why does socat UDP-RECVFROM terminate after exactly 1861 datagrams?

Time:02-15

Why does this terminate after exactly 1861 datagrams?

Host 2:

$ socat udp-recvfrom:12345,reuseaddr -

Host 1:

$ seq 1000000 | socat udp-sendto:host2:12345,reuseaddr -

On host 2, this prints out the lines:

0
1
...
1860

And then socat terminates with exit code 0, with no warning or error message.

I can't find any reference to this behaviour in the man page, or online. I can't find any reference to 1861 being some kind of special resource limit in Linux.

I'm using Linux kernel 5.16.7 (Arch) with socat-1.7.4.1.

EDIT: I think the problem here is my fundamental misunderstanding of what socat udp-recvfrom actually does. It only receives one datagram, and then terminates (as seen). So the issue is that the sender is combining a big chunk of seq output into a single datagram, which is then sent, and received as expected.

Therefore I think this question is resolved - thank you for your answers.

CodePudding user response:

Why does this terminate after exactly 1860 datagrams?

That's not what you see and that's likely not what happens either. What you see is that the server side receives data up to 1860 and not more. Since UDP is an unreliable protocol it says nothing on how many datagrams where actually sent - and then got lost somewhere. Doing an strace -e sendto on socat shows that the data actually gets transmitted to the socket, so it is not that socat has stopped sending.

Since you send the data as fast as possible it is very likely that most of them got lost, but nobody cared (it's UDP!). For example if I run the same script on localhost the last data I get depending on the current mood or load on the system is between 20000 and 35000. Slowing down socat (by running it within strace and logging output) gives much more data since the receiver can better keep up with the sender.

seq 1860 is about 8k data. Thus what you see could be explained by a socket write buffer of about 8k which gets very quickly filled up using seq and then more slowly emptied when sending the data. Everything which does not fit into the socket buffer gets simply and silently discarded. Similar things happen on the receiver side: if the receiver cannot read fast enough the read buffer will fill up and already transmitted data get discarded instead of being transferred to the application.

socat does not complain if packet got lost (it's UDP). It does not even complain if there is no process receiving any packets at all, i.e. if all data got lost.

Apart from that: it is not 1860 datagrams. It is actually a single datagram with a size of 8192 which gets received in your case. socat does not treat each line as a single message but instead reads and transmits in chunks of 8192 bytes.

CodePudding user response:

According to the man page. 8192 bytes is the block size used by socat, and is also the number of bytes generated by seq up to 1860. So it appears to be stopping after transferring one block.

  • Related