send()总是发送整个缓冲区吗?

时间:2012-09-29 22:27:33

标签: c linux sockets

send()将返回发送的字节数或错误代码,但我发现的所有示例都只检查错误代码,但不检查发送的字节数。

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

3 个答案:

答案 0 :(得分:13)

问:“send()”是否总是返回整个缓冲区?

<答>答:不,不一定。

来自Beej的指南:   * http://beej.us/guide/bgnet/html/multi/syscalls.html#sendrecv

  

send()返回实际发送的字节数 - 这可能是   少于你告诉它发送的数字!看,有时你告诉它   发送一整堆数据,它无法处理它。它会开火   关闭尽可能多的数据,并相信你发送其余的数据   后来。请记住,如果send()返回的值与   len中的值,由你来发送其余的字符串。好的   新闻是这样的:如果数据包很小(小于1K左右),它就会   可能设法将所有东西一次性发送出去。再次,-1是   错误时返回,并将errno设置为错误号。

问:“recv()”是否始终读取整个缓冲区?

答:不,绝对不是。您应该永远假设您收到的缓冲区是“整条消息”。或者假设您收到的消息来自一个单个消息。

这是一个很好的简短解释。它适用于Microsoft / C#,但它适用于所有套接字I / O,任何语言:

答案 1 :(得分:4)

答案在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.

或者,POSIX版本(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.

因此,虽然read部分数据很常见,但阻止模式中的部分send不应发生(除非实施细节)。

答案 2 :(得分:3)

不,它没有。

供参考,请参阅the man page for send

  

当消息不适合套接字的发送缓冲区时,发送()   除非套接字处于非阻塞I / O模式,否则通常会阻塞。   在非阻塞模式下,它将失败并出现错误EAGAIN或EWOULDBLOCK   案件。 select(2)调用可用于确定何时可以发送   更多数据。