我面临以下情况:
我有几个设备(运行ARCH Linux的嵌入式设备),我希望随时可以对每个设备进行管理访问。问题是设备在NAT后面,因此无法建立从服务器到设备的连接。我怎么能实现这个目标?
我以为我可以在设备上运行一个简单的服务,在启动时打开与服务器的连接。此TCP连接保持打开状态,可以从服务器使用以管理设备。但是长时间保持TCP连接打开是个好主意吗?如果我有很多设备,例如1000,我会在服务器端遇到1000个开放TCP连接的问题吗? 还有其他办法吗?
非常感谢!
答案 0 :(得分:2)
但是长时间保持TCP连接打开是个好主意吗?
这不一定是个坏主意;虽然在实践中连接会不时失败(例如,由于网络重新配置,临时网络中断等),因此您的客户端应包含在发生这种情况时自动重新连接的逻辑。另请注意,当完全空闲的TCP连接不再具有连接时,TCP通常不会检测到它,因此为了避免实际未连接的“僵尸连接”,您可能想要启用SO_KEEPALIVE,或者让您的客户端和/或服务器在套接字上发送(非常偶然的)虚拟数据,只是为了使TCP堆栈检查插槽上是否仍然存在连接。
如果我有很多设备,例如1000,我会在服务器端遇到1000个开放TCP连接的问题吗?
扩展绝对是您需要考虑的问题。例如,select()通常实现为仅处理固定数量的连接(通常为1024),或者如果您的服务器使用每个连接的线程模型,您会发现具有1000+个线程的进程是不是很有效率。查看c10k problem article,了解有关各种方法以及它们扩展(或不扩展)的大量有趣详细信息。
还有其他办法吗?
如果您不需要立即访问客户端,您可以随时定期检查(例如每5分钟一次);或者你可以让他们偶尔向服务器发送一个UDP数据包,而不是一直保持TCP连接,只是为了让服务器知道他们的存在,并让服务器以某种方式向他们指示(例如通过更新一个众所周知的网页当客户想要其中一个打开完整的TCP连接时,客户端会不时检查。或者只是使用多个服务器来共享负载...
答案 1 :(得分:1)
我所知道的唯一限制是iptables
代码中的状态跟踪。如果您正在使用它,请检查双方net.ipv4.netfilter.ip_conntrack_max
的值,以确保您有足够的空间用于其他活动。
如果在SO_KEEPALIVE
调用之前设置套接字选项connect()
,内核将发送TCP keepalives以确保远端仍在那里。这意味着在重启时连接不会永远存在。