TCP 连接:一段时间后,服务器无法将数据包发送到客户端.不过客户可以



我认为它只与TCP层有关,但我在以下段落中描述了我的设置:

在谷歌计算引擎上,我设置了一个http和websocket服务器(python,geventwebsocket+gevent。WSGIServer(。在家里,我有我的电脑(esp8266(,它使用网络插座连接到它。

我使用 websockets 是因为我需要双向通信(每天几条消息,它是这样的:来自服务器的消息,来自客户端的响应。连接本身由客户端启动,因为它位于 NAT 后面。

问题是,从上次数据包交换的几秒钟后,来自服务器的消息没有到达客户端。但是,客户端甚至可以在几分钟后(甚至可能更长(将数据包发送到服务器。有趣的是,可能从服务器重新传输的数据包终于到达了。

我检查了数据包确实是从带有wireshark的服务器发送的(如果不是ack'ed,则重新传输(并记录客户端上的每个网络通信,因此问题可能不是应用程序软件。我在应用程序中没有例外。连接已打开。

我测试了服务器在连接启动/上次交付数据包后可以发送数据包的时间,通常在 6 到 20 秒之间,两次测试之间有所不同。在测试服务器中,发送数据包之间有一组固定的延迟。

在具有单个设置延迟的测试(几个数据包(中,通常要么所有数据包到达,要么没有(是的,如果一个没有到达,下一个不会(。

我怀疑这可能是因为 NAT。但是,我看到的一种解决方案是定期(每6秒或更短(从客户端发送保持活动数据包(websocket中的ping和Pongs,或TCP的保持活动(。但这似乎并不优雅,因为一天应该只有几条数据消息。

从我的桌面到服务器进行ssh时也会发生类似的事情:在我服务器端处于非活动状态几秒钟后,服务器停止发送任何内容(例如使用watch -n20 date进行测试。有时它只是冻结并且不会更新,直到我按下一个键 = 从客户端发送数据包。但是在ssh的情况下,更新不是即时的,在按键后需要几秒钟才能看到新的东西。编辑:当然那一定是由于重传定时器算法(


所以我研究了TCP保持活动数据包等的目的是什么,问题是路由器和NAT在一段时间内忘记连接或映射或其他任何东西/只保留最新的。(所以我想在客户端>服务器的情况下,映射只是重新创建,因为目标 ip 是公共的并且是实际的服务器。而在相反的方向上这是不可能的,所以它不起作用。

但没想到它可以像 6 秒内那么糟糕。websocket 几乎减少到轮询(尽管延迟可能更小(。

似乎路由器的 NAT 机制可能会导致问题。也许你可以看到一些小工具,如NAT-PMP或Upnp来打开端口并映射到你的本地客户端。这将持续足够长的时间,以便您进行双向通信。

最新更新