不同浏览器发送TCP/IP RST的方式不同

3
在Mac OS X(10.6)上,如果我开始下载YouTube视频,并在拔掉以太网电缆5秒左右后重新插入,那么根据浏览器的不同,结果会有所不同。使用Opera和Chrome,在插回电缆后视频继续加载。但是在Safari和Firefox中,它永远不会加载。
使用Wireshark查看流量,我发现Opera和Chrome在插入电缆后仅对来自YouTube的第一个数据包进行确认,但Safari和Firefox在TCP头中设置RST标志(0x4),并且没有更多的流量跟随。
我可以在机器和互联网连接之间放置一个HUB,问题就消失了,所有四个浏览器在将电缆重新插入HUB时都继续加载视频。再次查看Wireshark日志,很明显机器没有看到多播连接关闭,只是数据包的流动有所延迟。
因此,似乎如果Safari和Firefox看到多播连接关闭,然后稍后在同一连接上看到数据,它们将发送RST。
我的问题是为什么?正确的做法是什么?为什么2/4个浏览器以这种方式进行,而另外2/4个以另一种方式进行?例如,在Firefox中是否可以看到此处正在发生的位置的代码?
非常感谢。

这很奇怪,我原本不认为浏览器会到达ACK数据包的级别 - 除非这是网络堆栈的工作,除非这是浏览器以不同方式处理来自网络堆栈的错误信号的方法。 - Andy Shellam
这非常有趣。我以前没有处理过 Mac,你确定所有浏览器都使用相同的 Flash Player 吗? - Sinan Taifour
3个回答

2
我意识到这是一个老问题,但我认为需要提供更详细的信息,因为我遇到了类似的问题,并且很难找到任何资源。根据我的经验和卡尔加里大学计算机科学系的一项研究,作者发现关于TCP RST数据包响应:
“...... 应用程序级浏览器行为是全球异常TCP行为的主要贡献者。具体而言,持久HTTP连接的实现和管理中的不规则性是此问题的原因。纠正流行Web浏览器的TCP行为可能会消除大部分这些TCP RST异常。”
基本上,这表明浏览器以不同的方式实现TCP重置行为,因此您会看到不同的行为。此外,似乎不同的操作系统也以不同的方式实现TCP RST头文件,因此即使在不同的操作系统上使用相同的浏览器也可能导致略有不同的结果,这可能是为什么在中间添加集线器可以解决该问题的原因。
我认为 Chromium bug 追踪器中的这个问题与 Chrome 的工作原理 有关。类似的事情在 2010 年 Firefox 中引入

当新套接字组的连接时间过长时,发出单个备份套接字请求以重试连接。这减少了丢包的延迟。

一些浏览器会在收到单个 RST 数据包时积极地终止连接(根据我的测试,IE 11/Safari 9/10 至少如此)。Google Chrome(经过 v56 测试)根据 chrome://net-internals 中的数据,似乎会重用相同的套接字在收到 ERR_CONNECTION_RESET -103 错误后进行重试。然后它会尝试几次,直到成功。我认为这种智能的重试行为可能是导致某些浏览器重新启动丢失连接的原因。虽然它可能没有实现适当的 RFC 或规范(我找不到确切的一个,它可能是针对 HTTP/1.1 或仅仅是 TCP Resets)。

我今天的经验涉及到在Big-IP F5 WAF/负载均衡器后面的Apache上启用了Keep Alive,并根据URL模式将流量路由到两个虚拟服务器组中的一个。关闭Apache中的Keep Alive解决了我们遇到的TCP RST数据包返回和连接中止的问题。

1

看起来Firefox和Safari在检测到多播连接关闭时会从其打开的连接列表中删除TCP连接。

TCP连接一旦关闭,当尝试向其发送数据包时,合理的行为是发送RST数据包。


1
当您拔掉电缆时,您的接口会关闭,并且随后的数据包应该会收到“ICMP NO ROUTE TO HOST”的消息。然后由应用程序决定如何处理:立即放弃还是等待更长时间?看起来Firefox和Safari不会等待更长时间。
当您保留集线器时,您的计算机不知道已经失去了到主机的路由,因此不会出现该消息。
希望对您有所帮助,

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接