【问题标题】:When BSD socket reports that RST was received, if not everything was read yet当 BSD 套接字报告收到 RST 时,如果尚未读取所有内容
【发布时间】:2015-06-16 09:52:48
【问题描述】:

让我们想象一下从服务器发送到客户端的以下数据序列:

[data] [data] [data] [FIN] [RST]

假设我在客户端执行以下操作(套接字是非阻塞的):

char buf[sizeof(data)];
for (;;)
{
    rlen = recv(..., buf, sizeof(buf), ...);
    rerr = errno;
    slen = send(..., "a", 1, ...);
    serr = errno;
}

我什么时候会看到ECONNRESET 错误?

我对以下极端情况特别好奇。让我们假设上面想象的序列的所有 IP 帧都已被 TCP 堆栈接收并ACKed。但是,我的客户端应用程序还没有 send()recv() 任何东西。第一次调用send() 会返回ECONNRESET 吗?如果是这样,下一次对recv() 的调用是否会成功并允许我在开始报告ECONNRESET 之前读取它在其内部缓冲区中的所有内容(因为它接收到数据并拥有它)(或由于FIN 而返回0) )?或者会发生什么不同的事情?

我将特别感谢解释该情况的文档中的链接。我正在尝试 grok linux tcp implementation 来解决这个问题,但还不是很清楚......

【问题讨论】:

    标签: c sockets tcp


    【解决方案1】:

    第一次调用 send() 会返回一个 ECONNRESET 吗?

    除非它阻塞足够长的时间以使对等方检测到断开连接的传入数据包并返回 RST。大多数时候,send 只会缓冲数据并返回。

    下一次调用 recv() 会成功吗

    这完全取决于 (a) 是否有传入的要读取的 a 以及 (b) 是否已经接收到 RAT。

    并允许我在开始报告 ECONNRESET(或由于 FIN 而返回 0)之前读取它在其内部缓冲区中的所有内容(因为它收到并拥有数据)?

    如果接收到 RST,所有缓冲的数据都将被丢弃。

    这完全取决于时间和两端缓冲区的大小。

    【讨论】:

    • “如果收到 RST,所有缓冲的数据都将被丢弃”——这几乎回答了我的问题。然而,这感觉不对(丢弃 RST 上的数据)。在哪里可以找到此类行为的确认信息?
    • 找到这个:blog.olivierlanglois.net/index.php/2010/02/06/… 看起来是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多