保持TCP连接处于活动状态,以跟踪哪些客户端在线

我正在开发一个服务器需要与大量简单的物联网设备保持联系的应用程序。 服务器和每个设备之间几乎不需要信息交换,但是设备需要保持联机并且可以在服务器上24小时到达。 在某些情况下(很less发生这种情况),服务器需要能够与其中一台设备联系并交换一些消息:但是,至关重要的是,这些设备在很短的时间内是可以到达的。

这意味着我需要这些客户端设备以某种方式连续连接。 现在,我想知道:通过TCP连接这些设备是否可行,并保持这些连接处于活动状态,随时准备交换消息?

我尝试过四处阅读,而且总是阅读相同的答案: 这取决于您的实现,因为您的消息交换和处理很可能是瓶颈,而不是保持这些TCP连接处于活动状态 。 现在,这不是我的情况,因为我只需要每隔很多时间就交换非常有限的信息量。

那么保持这些客户端连接是否合理呢? 或者我应该devise一个更有效的方法? 例如,在没有任何数据交换的情况下,只需保持一个TCP连接的活性就需要多less带宽? 这是否需要大量的内存或CPU?

我实现了一个简单的C ++程序,它每隔几秒就发送一次UDP给我的服务器。我的基准testing可以在没有任何问题的情况下扩展到数百万个在线设备上,即使是在一个相当有限的服务器上。 TCP会比这更差吗?

至于我对TCP的理解,断言“ 保持TCP连接处于活动状态 ”是有误导性的,因为当涉及到ESTABLISHED连接时, 没有处理超时的TCP协议特定机制。 我的意思是:一旦build立,它们可以永远持续下去,直到发生RESET,FIN或接收到ACK的超时(…在某些传输被确认后,在最后一种情况下)。

至于我的经验,100%的“ 因空闲超时而突然中断 ”的问题,依赖于中间路由器/防火墙,沿着两台通信主机之间的路由path。 我的意思是:由于防火墙是一个“有状态的”防火墙,因此它会跟踪防火墙/pipe理的连接。 因此,需要跟踪的每个连接意味着要消耗一定程度的系统资源(我的意思是指防火墙)。 此外,由于防火墙本身的特性(它是一个有状态的防火墙!),防火墙完全知道哪个被pipe理的连接“正在工作”,哪个被反过来“空闲”。 因此,许多(所有?)防火墙实现都有一个超时定义,如果pipe理连接对于这样一个timout值是空闲的,那么防火墙会向两端(TCP连接的…)发送一个复位并释放自己的资源。

基于你的问题,我敢打赌,你的IoT设备(充当客户端)与控制服务器(TCP服务器)将打开TCP连接。 因此,如果不是所有的ADSL归属路由器,将会对你的物联网设备stream量进行NAT转换,那么它肯定会像所描述的那样起作用。

至less,这是基于我自己的经验。

但是因为我不是Jon Postel ,请不要怪我,如果我错了:-)

作为一个方面说明:你写了“ …简单的物联网设备… ”。 请记住,你可以用一个单一的大型服务器处理的并发TCP连接数量非常严格。TCP“port”是一个16位的值。 因此,对于每个IP地址,不能超过(通过TCP本质devise)64K连接。 如何解决这个问题,在这个问题的背景下,这个问题超出了范围。

最后,让我补充一点,在IoT设备和pipe理服务器/应用程序之间实现一种心跳协议时,我确实没有遇到任何问题。 它的实施可以非常“networking化”,在带宽方面没有影响,而且在可pipe理性和可控性方面也有很多优势。

你的想法很好, 事实上,现代移动设备使用完全相同的方法来进行通知,它们与操作系统开发人员的服务器保持永久性连接,并且该服务器会按照该连接推送通知(第三方应用程序开发人员将通知发送给操作系统的开发人员,到适当的移动设备)。

如果您的设备保证有可公开路由的IP并且能够侦听套接字,则可以使用其他方法; 在这种情况下,设备会在每次IP更改时通知您的服务器,但是只要服务器需要将某些数据传送到设备,服务器就会连接到设备的套接字并向其发送数据。 这样,您的服务器就不需要处理任何负载,除了更新数据库中的每个设备的IP地址,偶尔连接到设备并发送数据。

关于TCP vs UDP,我相信TCP可以更好地保证设备的可达性 – 只要TCP连接打开,你可以保证设备仍然在那里(否则连接将会超时)。 使用UDP,你只需要将数据包扔到空中,而不必知道它们是否已经到达目的地(除非你实现了自己的保活,连接pipe理和重传系统,但是为什么当你已经有一个固体和stream行的实现称为TCP?)。 你也必须考虑防火墙和NAT,在build立TCP连接后,你确信你发送的任何东西都会到达目的地,而使用UDP则不能确定,必须通过不同程度的成功。