9

I have some problems understanding the working of sockets in Linux.

setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(int));
write = write(sockfd, buf, len);

In the above code as writes are buffered, send timeout doesn't make any sense(write system call will return immediately when the user space buffer is copied into the kernel buffers). Send buffer size is much more important parameter, but send timeout seems it does nothing worthwile. But I am certainly wrong, as I have seen quite a lot of code which uses SO_SNDTIMEO. How can user space code timeout using SO_SNDTIMEO assuming that the receiver is very slow?

0xhacker
  • 1,091
  • 2
  • 14
  • 26
  • Can you clarify what result you are trying to achieve? – Alexey Feldgendler Nov 26 '12 at 00:11
  • 2
    There is no result that I am trying to achieve, I have asked this question to understand the working of sockets and in particular why does SO_SNDTIMEO even exist? – 0xhacker Nov 26 '12 at 00:23
  • This answer might help you understand SO_SNDTIMEO: http://stackoverflow.com/a/4182564/10682 – Alexey Feldgendler Nov 26 '12 at 00:28
  • 1
    @Alexey Feldgendler - this is valid question. If SO limited itself to "practical" they would have to delete 20% of the questions. There have been plenty of mind numbingly obscure questions asked and answered here. – Duck Nov 26 '12 at 00:56
  • 1
    The only reason I can think of for setting `SO_SNDTIMEO` on a non-blocking socket is that somewhere in the codebase, the socket gets set back to blocking mode (maybe just temporarily for a particular operation), and the code's author wanted the socket to have a timeout during the time(s) it is set back to blocking mode. (Or, just as likely, the application was originally written to use blocking-mode sockets, and was later converted to use non-blocking sockets instead, and the code's author simply forgot to take out the now-unnecessary SO_SNDTIMEO calls) – Jeremy Friesner Feb 03 '19 at 20:41

2 Answers2

13

How is it possible to have send timeout on a non blocking socket?

It isn't. Timeouts are for blocking mode. A non-blocking recv() or send() won't block, and therefore cannot time out either.

I have seen a lot of code which uses SO_SNDTIMEO.

Not in non-blocking mode, unless the code concerned is nonsense.

If you want a timeout in non-blocking mode, that's one of the things the timeout in select() is for.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • In linux how do you ensure that the send or write to a packet is blocking ie. write or send returns only when kernel has received the ACK for the entire length of the buffer (buffer will be broken down into multiple tcp packets) – 0xhacker Nov 26 '12 at 14:44
  • @mc_87 You can't. If you want an acknowledgement you will have to send one yourself at the application level. – user207421 Nov 26 '12 at 18:03
  • So, then how will SO_SNDTIMEO be useful ever if at application level I can not block till my last tcp ack? – 0xhacker Nov 26 '12 at 21:00
  • @mc_87 Timeouts time out blocks that occur in blocking mode when you send into a full socket send butfer, or receive into an empty socket receive buffer. The part about waiting for an ACK when sending is just a figment of your imagination. TCP is a streaming protocol, not a request/response protocol. – user207421 Nov 26 '12 at 21:59
5

SO_SNDTIMEO is useful for a blocking socket. If the socket's buffer is full, send() can block, in which case it may be useful to use the SO_SNDTIMEO socket option. For non-blocking sockets, if the socket's buffer is full, send will fail immediately, so there is no point in setting SO_SNDTIMEO with a non-blocking socket.

Neal
  • 6,722
  • 4
  • 38
  • 31