marranxo
Posts: 30
Joined: Thu Dec 03, 2015 2:16 pm

send() blocks up to 30s

Mon Aug 29, 2016 2:35 pm

Hi,

I'm working on a project involving decoding video from a ip camera, processing it and sending in postprocessed and encoded to jpeg throw http.

Everythink works fine until send() starts to block (call time can be between 5ms and 30s [not ms]). I'm emiting 14 chunks of jpg encoded images per second of approx 20kbytes each chunk. As I've read in the send's man page, send call may block until there's enough space in kernel buffer to store the packet complelty or partially according to send result (>0 but < than full message size). Why is the reason raspberry can't afford sending 280-300KB/s throw a single connection?
I've increased the SO_SNDBUF with setsockopt to 2MB and the problem just gets delayed a bit. Also made the socket non-blocking with ioctl but more than 50% of calls to send() return -1 due to the send buffer being full I suppose.

Any tip to handle this situation?

Regards.

User avatar
kolban
Posts: 143
Joined: Fri Dec 04, 2015 1:45 am
Location: Texas, USA

Re: send() blocks up to 30s

Tue Aug 30, 2016 4:33 am

Its my understanding that the receiver can also ask the sender to stop sending new data ... for example, if you are sending data faster that the receiver can consume it, then trouble will ensue. For TCP connections, the receiver can cause the sender to block transmission. As such, it may not be an issue with the Pi but instead an issue with the receiver. There could also be some protocols at a higher level than the raw TCP transmission. Perhaps the sender and receiver have to exchange hand-shakes before the data will transmit.
FREE book on Raspberry Pi usage and programming

https://leanpub.com/pi

marranxo
Posts: 30
Joined: Thu Dec 03, 2015 2:16 pm

Re: send() blocks up to 30s

Tue Aug 30, 2016 8:23 am

The receiver is VLC media player in a windows 10 machine with good hw specs. Yes, HTTP is the higher protocol I'm using here to transmit the video. Encoded video frames arrive and are displayed correctly in the client but since I set the socket to non-blocking most of them are not send (-1) and I assume is due to the socket's buffer in kernel space because the last chunk before a sequence on send errors it's never send completly (ie 13000/20000 bytes sent) and subsequent sends fail with -1 until the kernel buffer associated with the socket gets some free space then send calls work properly until the buffer is full again, then again a incomplete frame is sent and a sequence os send fails (-1) and this behaivour continues indefinitly. In the other hand, if I don't set the socket tot non-block, send blocks until there's memory available in kernel space and by now the record is 30s wait.

In the other hand, I've installed iperf and performed some tests.
- as a server I'm receiving 83Mbits/s -> ~10000KB/s
- as a client I'm sending 38Mbits/s -> ~5000KB/s

This values are fine compared to 300KB/s I'm trying to send.

Return to “C/C++”