让我们想象一下从服务器发送到客户端的以下数据序列:
[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栈接收并ACK
。但是,我的客户端应用程序尚未send()
或recv()
。第一次拨打send()
是否会返回ECONNRESET
?如果是这样,下一次调用recv()
是否会成功并允许我在开始报告ECONNRESET
之前读取其内部缓冲区中的所有内容(因为它接收到数据并拥有它)(或者返回0,因为FIN
)?或者会发生不同的事情?
我将特别感谢解释这种情况的文档链接。我正在尝试使用linux tcp实现来解决这个问题,但它并不是那么清楚......
答案 0 :(得分:1)
第一次调用send()会返回一个ECONNRESET吗?
除非它阻塞的时间足够长,以便对等方检测到断开连接的传入数据包并返回RST。大多数情况下,send只会缓冲数据并返回。
下一次调用recv()会成功
完全取决于(a)是否有传入要读取的内容以及(b)是否已收到RAT。
并允许我在开始报告ECONNRESET(或因为FIN返回0)之前读取它在内部缓冲区中的所有内容(因为它接收到数据并拥有它)?
如果收到RST,则会丢弃所有缓冲的数据。
这一切完全取决于两端缓冲区的时间和大小。