6

When using blocking sockets on Linux, is there any reason for send() to return less than what was requested, other than an interrupted, but partially successful send() syscall?

I'm aware that this is possibly very implementation defined, and that it would probably be very dangerous to rely on that behavior even without any installed signal handlers (and thus reasons for interrupted syscalls). I'll probably loop around the send call until completion; however, if there were any official word on the matter, I would be able to avoid that.

Why is it assumed that send may return with less than requested data transmitted on a blocking socket? was asking the same question, with inconclusive results: Interrupted syscalls are mentioned as an example for a short return count, but it's still unclear whether a full TCP send buffer would cause a partial send or the send() would just block until there is enough room in the buffer.

tshepang
  • 12,111
  • 21
  • 91
  • 136
lxgr
  • 3,719
  • 7
  • 31
  • 46

1 Answers1

4

In general, if the transmit buffer contains some space, but not enough for the entire send request then it will send as much as it can and then return the amount actually added to the buffer -- a short write.

Now you could argue that it would make more sense to block (on a blocking socket), but the reason it doesn't is historical -- TCP is based on UNIX pipes, and that's the way UNIX pipes worked. The main reason is that it makes corner cases (in the kernel) easier -- you don't have to worry about blocking a system call in the middle of doing something; it either does something and returns immediately or does nothing and blocks until some event (at which point the kernel retries it from scratch). You don't have to worry about what happens if someone tries to write more than the maximum buffer size in a single write (which might otherwise cause a deadlock).

tshepang
  • 12,111
  • 21
  • 91
  • 136
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • FWIW, the man page for `send()` on my Linux box says `When the message does not fit into the send buffer of the socket, send() normally blocks, unless the socket has been placed in nonblocking I/O mode. In nonblocking mode it would fail with the error EAGAIN or EWOULDBLOCK in this case.` It does not seem to document the function as returning anything other than its `len` argument (or `-1` on error). – Frédéric Hamidi Jan 17 '12 at 19:55
  • 2
    Linux man pages are notoriously vague. You're much better off checking the page on a BSD system. The RETURN VALUES section documents that it just returns the number of characters sent with no guarantee that it's the same as the number requested. – Chris Dodd Jan 25 '12 at 17:01