让我们想象一下从服务器发送到客户端的以下数据序列:
[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/