Does send() always send whole buffer?

2020-08-16 03:28发布

问题:

send() shall return the number of bytes sent or error code, but all examples that I found check it only with error codes, but not with the number of bytes sent.

//typical example
int cnt=send(s,query,strlen(query),0);
if (cnt < 0) return(NULL);
//Hey, what about cnt < strlen(query)?

回答1:

Q: Does "send()" always return the whole buffer?

A: No, not necessarily.

From Beej's Guide: * http://beej.us/guide/bgnet/html/multi/syscalls.html#sendrecv

send() returns the number of bytes actually sent out—this might be less than the number you told it to send! See, sometimes you tell it to send a whole gob of data and it just can't handle it. It'll fire off as much of the data as it can, and trust you to send the rest later. Remember, if the value returned by send() doesn't match the value in len, it's up to you to send the rest of the string. The good news is this: if the packet is small (less than 1K or so) it will probably manage to send the whole thing all in one go. Again, -1 is returned on error, and errno is set to the error number.

Q: Does "recv()" always read the whole buffer?

A: No, absolutely not. You should never assume the buffer you've received is "the whole message". Or assume the message you receive is from one, single message.

Here's a good, short explanation. It's for Microsoft/C#, but it's applicable to all sockets I/O, in any language:

  • http://blogs.msdn.com/b/joncole/archive/2006/03/20/simple-message-framing-sample-for-tcp-socket.aspx


回答2:

The answer is in another section of man 2 send:

   When the message does not fit into  the  send  buffer  of  the  socket,
   send()  normally blocks, unless the socket has been placed in nonblock‐
   ing I/O mode.  In nonblocking mode it would fail with the error  EAGAIN
   or  EWOULDBLOCK in this case.  The select(2) call may be used to deter‐
   mine when it is possible to send more data.

Or, alternatively, the POSIX version (man 3p send):

   If  space is not available at the sending socket to hold the message to
   be transmitted, and the socket file descriptor does not have O_NONBLOCK
   set,  send()  shall  block  until  space is available.  If space is not
   available at the sending socket to hold the message to be  transmitted,
   and  the  socket file descriptor does have O_NONBLOCK set, send() shall
   fail. The select() and poll() functions can be used to  determine  when
   it is possible to send more data.

So, while a read of partial data is common, a partial send in blocking mode should not happen (barring implementation details).



回答3:

Nope, it doesn't.

For reference, see the man page for send:

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. The select(2) call may be used to determine when it is possible to send more data.



标签: c linux sockets