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

send()应该返回发送的字节数或者错误码,但是我发现所有的例子只是用错误码检查,而不是用发送的字节数。

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

Solutions Collecting From Web of "send()总是发送整个缓冲区?"

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

答:不,不一定。

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

send()返回实际发送的字节数 – 这可能比你告诉它发送的数字少! 看,有时候你告诉它发送一个数据的整体,它不能处理它。 它会尽可能多的发送数据,并相信你稍后再发送。 请记住,如果send()返回的值与len中的值不匹配,则由您来发送字符串的其余部分。 好消息是,如果数据包很小(不到1K左右),那么可能会把所有的东西都发送出去。 同样,错误返回-1,errno被设置为错误号。

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

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

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

答案是在man 2 send另一部分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阻塞模式(禁止实现细节)。

不,不。

有关参考,请参阅send的手册页 :

当消息不适合套接字的发送缓冲区时,send()通常会阻塞,除非套接字已被置于非阻塞I / O模式。 在非阻塞模式下,在这种情况下会失败,出现EAGAIN或EWOULDBLOCK错误。 select(2)调用可以用来确定何时可以发送更多的数据。