使用阻止套接字时,我对发送功能的行为感兴趣。
本手册明确规定了 。
从我的测试(和文档)中可以看出,当在阻塞套接字上使用send时,我有两种情况:
在代码行中(例如在C中),这样翻译:
// everything is allocated and initilized
int socket_fd;
char *buffer;
size_t buffer_len;
ssize_t nret;
nret = send(socket_fd, buffer, buffer_len, 0);
if(nret < 0)
{
// error - nothing was sent (at least we cannot assume anything)
}
else
{
// in case of blocking socket everything is sent (buffer_len == nret)
}
我是对的吗?
我对所有平台(Windows,Linux,* nix)上的这种行为感兴趣。
答案 0 :(得分:1)
从手册页。 (http://linux.die.net/man/2/send)
“成功时,这些调用将返回发送的字符数。出错时,返回-1,并正确设置errno。”
你有三个条件。
-1是套接字中的本地错误或它的绑定。
一些数字&lt;长度:并非所有字节都被发送。当套接字被标记为非阻塞且请求的操作将被阻塞时,通常就是这种情况; errno值是EAGAIN。
你可能不会看到这个,因为你正在阻止I / O.
但是,插座的另一端可能会过早地关闭连接,这可能会导致这种情况发生。 errno值可能是EPIPE。
有些数字==长度:所有字节都已发送。
答案 1 :(得分:1)
我的理解是阻塞发送不必是原子的,例如参见Solaris send man page:
For socket types such as SOCK_DGRAM and SOCK_RAW that require atomic messages, the error EMSGSIZE is returned and the message is not transmitted when it is too long to pass atomically through the underlying protocol. The same restrictions do not apply to SOCK_STREAM sockets.
还要查看那里的EINTR错误代码:
The operation was interrupted by delivery of a signal before any data could be buffered to be sent.
这表示在缓冲某些数据发送后可以中断发送 - 但在这种情况下,send将返回已经缓冲发送的字节数(而不是EINTR错误代码)。
在实践中,我只希望在SOCK_STREAM套接字上看到大型消息(操作系统无法原子处理)的这种行为。