【问题标题】:socket behaviour when in blocking mode处于阻塞模式时的套接字行为
【发布时间】:2009-03-19 10:06:05
【问题描述】:

我对使用阻塞套接字时发送函数的行为感兴趣。

手册没有明确说明此案例

从我的测试(和文档)来看,当在阻塞套接字上使用 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)上的这种行为感兴趣。

【问题讨论】:

    标签: windows linux unix sockets


    【解决方案1】:

    来自手册页。 (http://linux.die.net/man/2/send)

    “成功时,这些调用返回发送的字符数。出错时,返回-1,并适当设置errno。”

    你有三个条件。

    • -1 是套接字中的本地错误或其绑定。

    • 某个数字

      你可能不会看到这个,因为你正在阻塞 I/O。

      但是,套接字的另一端可能会过早关闭连接,这可能会导致这种情况。 errno 值可能是 EPIPE。

    • 某个数字 == 长度:所有字节都已发送。

    【讨论】:

    • 现在我的问题是指您的回答:当我们有一个阻塞套接字时,您提出的第二种情况是否可能? (我在那里只看到模糊的词:“通常”、“可能”……)因为如果没有,那我是对的,只有 2 种情况。
    • 正如我所说,套接字的另一端可能会过早关闭。你“可能”会得到一个 EPIPE。我还没有在所有操作系统上实际测试过它以提供绝对的证据。你有三个案例。
    【解决方案2】:

    我的理解是阻塞发送不必是原子的,例如参见 Solaris send man page:

    对于 SOCK_DGRAM 和 SOCK_RAW 等需要原子消息的套接字类型, 返回错误 EMSGSIZE 并且消息在发送时不传输 太长而无法原子地通过底层协议。相同 限制不适用于 SOCK_STREAM 套接字。

    还要查看那里的 EINTR 错误代码:

    在任何数据可以之前,操作被信号的传递中断 被缓冲发送。

    这表明在一些数据被缓冲发送后可以中断发送 - 但在这种情况下,发送将返回已经缓冲发送的字节数(而不是 EINTR 错误代码)。

    实际上,我只希望在 SOCK_STREAM 套接字上看到大型消息(操作系统无法自动处理)的这种行为。

    【讨论】:

      猜你喜欢
      • 2012-02-15
      • 1970-01-01
      • 2011-08-19
      • 1970-01-01
      • 2011-12-18
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多