我正在使用python开发客户端 - 服务器游戏,我想了解更多有关端口转发的信息。
我正在做的是转到我的路由器(192.168.0.1)
并将其配置为允许将我的真实IP地址请求重定向到我的本地地址192.168.0.X.
它的效果非常好。但是我想知道我是否可以通过自动编码来实现它?
我认为skype就像一种p2p
,我可以在我的路由器中看到Skype自动端口转发到我的电脑地址。我也可以用Python做吗?
答案 0 :(得分:11)
这里有不同的解决方案,但大多数都不是微不足道的,你必须做一些阅读,你需要某种后备。
UPnP/IGD是最简单的。如果您的路由器支持它,并且配置为允许它,并且您知道如何编写低级网络代码或旧式SOAP Web服务代码,则可以要求路由器为您分配端口。如果它成功响应,请开始使用该端口,基本上完成了。
如果您可以为所有用户运行带有公共地址的(超低带宽)服务器,Hole punching可能会解决问题。
考虑一下NAT客户端如何与公共服务器通信。你向某个IP和端口发出请求,但服务器看到你的路由器的IP,而不是你的(这是一件好事,因为你的无法访问)。当它回复时,您的路由器必须知道将它转发给您 - 只需记住您是刚刚向该服务器发送请求的NAT客户端。
如果您不与公共服务器通信,而是与他自己的独立NAT后面的其他同行交谈,该怎么办?好吧,你的路由器不知道区别;只要你从同一个地方得到回复,它就会通过。但是当你的消息无法通过他的NAT时,你如何得到回应呢?当然,他做同样的事情。其中一条消息可能会丢失,但另一条消息将通过,然后您已设置并可以进行通信。您需要定期发送保持活动,以便路由器不会忘记您正在进行通信,但除此之外,确实没什么棘手的。
唯一的问题是你需要知道另一个对等方的公共IP地址,以及他希望你来自的端口,他需要了解你的相同信息。这就是为什么你需要一台服务器来充当同伴之间的介绍人。
打孔将适用于来自大多数家庭网络的UDP。它不适用于许多家庭网络中的TCP,也不适用于来自许多公司网络的UDP或TCP。 (此外,在企业网络中,您可能有多层NAT,这意味着您需要在每个接口上使用介绍器,而不仅仅是互联网上的介绍者,或者无法打孔的对称NAT。)
您可以使用STUN(或类似)服务,例如ICE或TURN。这只适用于有使用ICE,TURN等服务的情况 - 对于不同家庭NAT上的两个对等体通常不是这种情况,除非您部署自己的服务器并构建一个介绍人来帮忙,如果你是要做到这一点,你可以只使用打孔。但在企业环境中,这可能是为P2P应用程序提供连接的最佳方式。
最后,您可以让用户手动配置端口转发,并在您的问题中输入转发的端口号。这并不理想,但您应该始终将其作为后备(除了仅适用于公司部署的应用程序),因为其他任何内容都不适用于所有用户。
我相信Skype使用了所有这些。如果启用UPnP,它会尝试IGD您的路由器。或者您可以将其配置为使用TURN服务器。或者您只需输入您手动转发的特定端口即可。如果您不执行上述任何操作,它会尝试使用UDP打孔,并使用Skype运行的介绍人。
答案 1 :(得分:2)
因此,如果我理解正确,您的应用程序需要进行TCP / UDP网络连接。这意味着至少有一个连接客户端需要一个正确打开的端口,如果它们都在NAT(路由器)之后且没有配置开放端口,则客户端无法连接。
有几种可能的解决方案,但并非所有解决方案都可靠:UPnP,如此处所建议的,可以按需打开端口,但不支持(或启用)所有路由器(并且它是安全威胁),并且P2P解决方案很复杂,但仍需要某些客户端上的开放端口。
唯一可靠的解决方案是拥有一个专用服务器,所有客户端都可以连接到该服务器来协商连接,并可能在它们之间进行代理。
答案 2 :(得分:0)
您可以查看类似的内容(假设您的路由器支持它):http://en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal
答案 3 :(得分:-1)
为了使用python实现端口转发,有一个很棒的ActriveState配方,只使用Python标准库(套接字,晕厥)来执行异步端口转发服务器。看看
http://code.activestate.com/recipes/483732-asynchronous-port-forwarding/