c - 当 BSD 套接字报告已收到 RST 时,如果尚未读取所有内容

标签 c sockets tcp

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

[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 帧都已收到并且 ACK由 TCP 堆栈编辑。但是,我的客户端应用程序没有 send()recv()还没有什么。请先调用send()返回ECONNRESET ?如果是这样,下次会调用recv()吗?成功并允许我在开始报告 ECONNRESET 之前读取其内部缓冲区中的所有内容(因为它收到了数据并拥有数据) (或由于 FIN 返回 0 )?或者会发生一些不同的事情?

我将特别感谢解释这种情况的文档链接。我正在尝试 grok linux tcp 实现来弄清楚这一点,但还不是那么清楚......

最佳答案

Will the first call to send() return an ECONNRESET?

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

will the next call to recv() succeed

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

and allow me to read everything it has in its internal buffers (since it received the data and has it) before starting to report ECONNRESET (or returning 0 because of FIN)?

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

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

关于c - 当 BSD 套接字报告已收到 RST 时,如果尚未读取所有内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30864233/

相关文章:

c - 我已经使用 C 程序实现了简单的 bash 像 shell,但它没有按预期工作

javascript - nodejs 错误 : Parse Error at Socket. ondata

java - 使用套接字传输大文件

ruby - 如何在 ruby​​ 中创建非阻塞 TCP 服务器和 TCP 套接字,只有以下更改才会有所不同?

c - 带有Linux的C中套接字的奇怪段错误

c - 以 Unicode 写入文件

c++ - 调用函数时栈上有什么?

c - 尝试创建链接列表时出现段错误

c++ - 从 tcp 迁移到 udp 时,‘acceptor’ 不是 ‘boost::asio::ip::udp’ 的成员

mysql - '拨TCP 127.0.0.1 :3306: getsockopt: connection refused' when trying to run a docker image