Networking TCP连接:一段时间后,服务器无法向客户端发送数据包。但客户可以

Networking TCP连接:一段时间后,服务器无法向客户端发送数据包。但客户可以,networking,websocket,tcp,firewall,nat,Networking,Websocket,Tcp,Firewall,Nat,我认为它只与TCP层有关,但我将在以下段落中描述我的设置: 在google计算引擎上,我设置了一个http和websocket服务器(python,geventwebsocket+gevent.WSGIServer)。在家里,我的电脑(esp8266)通过WebSocket与之连接 我使用WebSocket是因为我需要双向通信(一天两条消息,它是这样的:一条来自服务器的消息,一条来自客户端的响应)。连接本身是由客户端启动的,因为它位于NAT后面 问题是,在最后一次数据包交换后的几秒钟内,来自服务

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

在google计算引擎上,我设置了一个http和websocket服务器(python,geventwebsocket+gevent.WSGIServer)。在家里,我的电脑(esp8266)通过WebSocket与之连接

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

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

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

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

在一个测试中(两个数据包),只有一组延迟,通常要么所有数据包都到达,要么没有(是的,如果一个数据包没有到达,下一个数据包就不会到达)

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

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


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


但没想到会有6秒钟那么糟糕。websockets几乎减少到轮询(尽管延迟可能更小).

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

这听起来好像NAT路由器的NAT表条目超时过短。设备在做什么NAT?它有任何相关的配置选项吗?有没有办法在NAT路由器的WAN端捕获数据包?@Gordon Davisson我只能访问最近的NAT路由器(还有更多——WAN地址与我的公共IP地址不匹配)。我可能可以在那里捕获数据包。你确定这不可能是非NAT IP路由器吗?它们不保留每连接表?这也是从美国到欧盟的路由。路由器对于这样的问题,NAT是最有可能出现的问题,但不是唯一可能出现的问题。同一TCP会话中的不同数据包采用不同的路由是正常的,因此普通路由器需要转发属于以前从未见过的会话的数据包。NAT路由器必须跟踪TCP会话,以便能够正确地传输延迟传入数据包(您看到的症状与我对NAT路由器不知道如何转换传入数据包的期望相符)。有些防火墙做类似的事情,所以这是另一个可能的疑点。Thx作为解释!我将查看路由器配置并尝试捕获一些数据包。但这只是一个NAT。听起来您的ISP正在使用CGN,因此您的路由器上不会有实际的公共地址。它要么是共享空间中的地址(ISP应该做什么)或某个私人空间中的地址(许多ISP都做什么,即使不建议这样做)。在任何一种情况下,您都无法控制ISP NAPT路由器,而且它可能故意设置了一个非常短的超时时间,因为您正在与许多其他ISP客户共享NAPT表。因此,我查看了IP地址(我的路由器和感知到的外部公共IP地址),根据这些地址判断,我至少支持三个NAT设备。我的路由器(我有控制权)和另外2个NAT,对于接近的一个,我可能知道IP地址,但对于另一个(s)我不知道。我可能会尝试执行跟踪路由,但否则我不知道如何发现地址。如果我知道所有地址,我可能会尝试使用您建议的协议保留端口映射:IGD、NAT-PMP或最新的PCP。我不知道前两种协议是否会在许多NAT之后工作。从我也不知道的最后一段判断,PCP可能会I don’我不知道ISP的硬件一般支持这些协议的范围有多广(以及这些服务是否在特定的路由器上启用)无论如何,这些协议都是为了解决我的问题而设计的。这些协议将把外部IP返回给你的客户机,不管你连接了多少NAT路由器,如果你的路由器支持它们,它在你的环境中都可以工作。如果不支持,也许你必须使用一个中央服务器来收集信息,然后充当一个代理