我有一个连接多个设备的客户端。未支付每台设备每月的静态 IP 费用。我们计划改变架构。在这个新的架构中,设备连接到服务器。而不是写一个服务器。我正在寻找一个中间解决方案。
当前架构:
-------------- ------------
| POLLER APP | ------------------------> | DEVICE 1 |
-------------- ------------
| |
| | ------------
| ---------------------------> | DEVICE 2 |
| ------------
|
| ...
|
| ------------
------------------------------> | DEVICE N |
------------
轮询器应用程序按顺序连接到具有静态 IP 的每个设备。
解决方案一:
-------------- ------------
| SERVER | <------------------------ | DEVICE 1 |
-------------- ------------
A A
| |
| | ------------
| --------------------------- | DEVICE 2 |
| ------------
|
| ...
|
| ------------
------------------------------ | DEVICE N |
------------
在这个解决方案中(我不喜欢)我必须为具有动态IP的设备编写一个服务器应用程序。
解决方案2(我正在寻找):
------------
-------------- | | ------------
| POLLER APP | ------------------------> | X | <------------ | DEVICE 1 |
-------------- | | ------------
| | | |
| | | | ------------
| ---------------------------> | | <------------ | DEVICE 2 |
| | | ------------
| | |
| ------------
|
| ------------
------------------------------> | DEVICE S |
------------
X Box 作为服务器。远程设备可以连接到此盒子并轮询器应用程序可以在本地或通过 Unix 域套接字连接到该服务器。 X Box 重复来自本地连接到远程设备的消息。
我的问题是:有没有完整或部分的解决方案可以帮助我实现这一目标。我可以轻松地直接绑定两个传入连接吗?
答案1
根据轮询器联系设备的频率,使用可能就足够了动态域名解析。使用动态 DNS,您根本不需要静态 IP 地址,只需要由支持动态 DNS 的提供商控制的域名。每次设备(重新)连接时,它都会连接到 DNS 提供商以声明其新的 IP 地址。这种方法的缺点是 DNS 信息需要几分钟的时间才能传播,因此每次 IP 地址发生变化时,您的设备都会有几分钟的时间无法访问。
如果您想要一个具有静态 IP 地址的盒子,那么您正在寻找的就是NAT(网络地址转换)。这个想法是,当盒子 X 在某个端口上接收到传入的 TCP 连接时,它会查阅一个表来决定将连接转发到哪个设备(或为自己获取连接)。这种情况发生在 IP 数据包和 TCP 连接级别,因此您不需要在轮询器或设备上安装任何特殊软件,只需将轮询器配置为对每个设备使用相同的 IP 地址但使用不同的端口号。
几乎所有设备都支持 NAT。例如,家庭路由器就是这样做的,这样您就可以将多个设备(计算机、电话等)连接到互联网,即使您的互联网服务提供商只为您提供一个 IP 地址。在这种情况下,设备执行源NAT(SNAT):路由器将TCP连接的源修改为自身而不是计算机(反之亦然,修改另一个方向的数据包的目的地)。在您的情况下,您需要目标 NAT (DNAT),它会修改客户端→服务器方向上的数据包的目的地以及服务器→客户端方向上的数据包的源。如果设备需要打开与 Internet 上其他计算机的连接,您可以使 box X 同时执行 DNAT 和 SNAT。
在 Linux 上,您可以用来iptables
配置 NAT。请参阅网络过滤器操作方法或网络上众多 Linux NAT 教程中的任何一个。
答案2
我为此编写了一个 Python 脚本。也许有更短的方法来实现这一目标,但我找不到。我的脚本创建 1 个外部服务器,用于侦听 1560 设备连接。对于每个设备连接,它都会创建一个新的内部服务器。在这之后。它在匹配的内部和外部连接之间传输消息。
B I N D E R
-------------
| INT | E | ------------
-------> (60000) | SRV | X | (1560) <------- | DEVICE 1 |
| | T | ------------
|-----| E |
| INT | R | ------------
-------> (60001) | SRV | N | (1560) <------- | DEVICE 2 |
| | A | ------------
|-----| L |
| INT | | ------------
-------> (60002) | SRV | S | (1560) <------- | DEVICE 3 |
| | E | ------------
|-----| R |
| INT | V | ------------
-------> (60003) | SRV | E | (1560) <------- | DEVICE 4 |
| | R | ------------
-------------
该脚本需要python-twisted
依赖。我为此创建了一个 github 存储库:github.com/codvio/binder