我正在尝试设置 iptables 以在 docker 容器之间引起真实的网络故障。在服务器上,我运行了netcat -lk 1234
和 Erlang cowboy 服务器。在客户端上,我运行了客户端:
echo blah | netcat myserver 1234
curl myserver/xyz
最初,这些工作正常,有证据表明客户端与服务器通信。接下来,我在客户端的 OUTPUT 上引入 iptables DROP 规则。
iptables -A OUTPUT -j DROP
echo blah | netcat myserver 1234
curl myserver/xyz
netcat 和 curl 通信均无法进行,直到我删除了 DROP 规则,此时它们就无缝恢复了!
最后我重复上述操作,但在删除 DROP 规则之前,我按 ctrl-c 删除了客户端可执行文件。删除 DROP 规则后,我没有发现服务器收到客户端请求的证据。
我的结论是,netat/curl 客户端肯定在尝试无限期地重新传输?难道我最终不会失败吗?顺便说一句,使用其他客户端时也会发生同样的事情,例如 Erlang http/websocket_client。
答案1
是的,TCP 会尝试在不可靠的网络上建立可靠的连接,因此它能够容忍一定程度的数据包丢失。发送方会不断重试发送数据,直到收到接收方的 ACK,或者直到超时并确定连接已丢失。
根据这个帖子,在Linux上发送数据的默认超时时间刚好超过2分钟。
(如果两个端点都没有发送数据,它们可能根本就不会发现连接中断,除非它们配置为发送 TCP 保持活动消息。但是,默认情况下,TCP 保持活动消息在 2 小时不活动后发送。)