简体   繁体   English

Python端口转发

[英]Python port forwarding

I'm developing a client-server game in python and I want to know more about port forwarding. 我正在开发python中的客户端 - 服务器游戏,我想了解更多有关端口转发的信息。

What I'm doing for instance is going to my router (192.168.0.1) and configure it to allow request for my real IP-adress to be redirected to my local adress 192.168.0.X. 我正在做的是去我的路由器(192.168.0.1)并配置它以允许我的真实IP地址的请求被重定向到我的本地地址192.168.0.X. It works really well. 它工作得很好。 But I'm wondering if I can do it by coding something automatically ? 但我想知道我是否可以通过自动编码来做到这一点?

I think skype works like a kind of p2p and I can see in my router that skype is automatically port forwarded to my pc adress. 我认为skype就像一种p2p ,我可以在我的路由器中看到Skype自动端口转发到我的电脑地址。 Can I do it in Python too? 我也可以用Python做吗?

There are different solutions here, but most are not trivial, and you'll have to do some reading, and you'll need some kind of fallback. 这里有不同的解决方案,但大多数都不是微不足道的,你必须做一些阅读,你需要某种后备。


UPnP/IGD is the simplest. UPnP / IGD是最简单的。 If your router supports it, and is configured to allow it, and you know how to write either low-level networking code or old-fashioned SOAP web service code, you can ask the router to assign you a port. 如果您的路由器支持它,并且配置为允许它,并且您知道如何编写低级网络代码或旧式SOAP Web服务代码,则可以要求路由器为您分配端口。 If it responds with success, start using that port and you're basically done. 如果它成功响应,开始使用该端口,你基本上完成了。


If you can run a (very low-bandwidth) server with a public address for all of your users, Hole punching may solve the problem. 如果您可以为所有用户运行带有公共地址的(极低带宽)服务器,则打孔可以解决问题。

Think about how a behind-the-NAT client talks to a public server. 想想NAT后面的客户端如何与公共服务器通信。 You make a request to some IP and port, but the server is seeing your router's IP, not yours (which is a good thing, because yours isn't accessible). 你向某个IP和端口发出请求,但服务器看到你的路由器的IP,而不是你的(这是一件好事,因为你的无法访问)。 When it replies, your router has to know to forward it to you—which it does just by remembering that you're the behind-the-NAT client that just sent a request to that server. 当它回复时,您的路由器必须知道将它转发给您 - 只需记住您是刚刚向该服务器发送请求的NAT客户端。

What if, instead of talking to a public server, you talk to some other peer behind his own separate NAT? 如果您不是与公共服务器交谈,而是与他自己独立的NAT后面的其他同行交谈,该怎么办? Well, Your router doesn't know the difference; 好吧,你的路由器不知道区别; as long as you get a response from the same place, it'll get through. 只要你从同一个地方得到回复,它就会通过。 But how do you get a response, when your message isn't going to get through his NAT? 但是当你的消息无法通过他的NAT时,你如何得到回应呢? He does the same thing, of course. 当然,他做同样的事情。 One of the messages may get lost, but the other one will get through, and then you're both set and can communicate. 其中一条消息可能会丢失,但另一条消息将通过,然后您已设置并可以进行通信。 You will need to send keep-alives regularly so the router doesn't forget you were communicating, but other than that, there's really nothing tricky. 您需要定期发送保持活动,以便路由器不会忘记您正在进行通信,但除此之外,实际上并没有什么棘手的问题。

The only problem is that you need to know the public IP address for the other peer, and the port that he's expecting you to come from, and he needs to know the same about you. 唯一的问题是你需要知道另一个对等方的公共IP地址,以及他期望你来自的端口,他需要了解你的相同信息。 That's why you need a server—to act as an introducer between peers. 这就是为什么你需要一台服务器 - 作为同伴之间的介绍人。

Hole punching will work with UDP from most home networks. 打孔将适用于来自大多数家庭网络的UDP。 It won't work with TCP from many home networks, or with either UDP or TCP from many corporate networks. 它不适用于许多家庭网络中的TCP,也不适用于来自许多公司网络的UDP或TCP。 (Also, in corporate networks, you may have multiple layers of NATs, which means you need introducers at every interface rather than just one on the internet, or symmetric NATs, which can't be punched.) (此外,在企业网络中,您可能有多层NAT,这意味着您需要在每个接口上使用介绍器而不是互联网上的一个介绍器,或者无法打孔的对称NAT。)


You can use STUN (or similar) services like ICE or TURN. 您可以使用STCE (或类似)服务,如ICE或TURN。 This only works if there is an ICE, TURN, etc. service to use—which is generally not the case for two peers on different home NATs, unless you deploy your own server and build an introducer to help out, and if you're going to do that, you can just use hole punching. 这只适用于有使用ICE,TURN等服务的情况 - 对于不同家庭NAT上的两个对等体通常不是这种情况,除非您部署自己的服务器并构建一个介绍人来帮忙,如果你是要做到这一点,你可以只使用打孔。 But in a corporate environment, this can be the best way to provide connectivity for P2P apps. 但在企业环境中,这可能是为P2P应用程序提供连接的最佳方式。


Finally, you can make the user configure port-forwarding manually and enter the forwarded port number into your problem. 最后,您可以让用户手动配置端口转发,并在您的问题中输入转发的端口号。 This is not ideal, but you should always provide it as a fallback (except maybe for apps meant only for corporate deployment), because nothing else is going to work for all of your users. 这并不理想,但您应始终将其作为后备(除了可能仅适用于企业部署的应用程序),因为其他任何内容都不适用于所有用户。


I believe Skype uses all of these. 我相信Skype使用所有这些。 If you enable UPnP, it tries to IGD your router. 如果启用UPnP,它会尝试IGD您的路由器。 Or you can configure it to use a TURN server. 或者您可以将其配置为使用TURN服务器。 Or you can just enter a specific port that you've forwarded manually. 或者您只需输入您手动转发的特定端口即可。 If you do none of the above, it tries to use UDP hole punching, with an introducer that Skype runs. 如果您不执行上述任何操作,它会尝试使用UDP打孔,以及Skype运行的介绍人。

So your application needs to do TCP/UDP networking if I understand correctly. 因此,如果我理解正确,您的应用程序需要进行TCP / UDP网络连接。 That means that at least one of the connecting clients needs a properly open port, and if both of them is behind NAT (a router) and have no configured open ports, your clients cannot connect. 这意味着至少有一个连接客户端需要一个正确打开的端口,如果它们都在NAT(路由器)之后并且没有配置的开放端口,则客户端无法连接。

There are several possible solutions for this, but not all are reliable: UPnP, as suggested here, can open ports on demand but isn't supported (or enabled) on all routers (and it is a security threat), and P2P solutions are complex and still require open ports on some clients. 有几种可能的解决方案,但并非所有解决方案都可靠:UPnP,如此处所建议的,可以按需打开端口,但不支持(或启用)所有路由器(并且它是安全威胁),P2P解决方案是复杂但仍需要某些客户端上的开放端口。

The only reliable solution is to have a dedicated server that all clients can connect to that will negotiate the connections, and possibly proxy between them. 唯一可靠的解决方案是拥有一个所有客户端都可以连接的专用服务器,它将协商连接,并可能在它们之间进行代理。

你可以看看这样的东西(假设你的路由器支持它): http//en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal

For implementing port forwarding using python, there's a fantastic ActriveState recipe that does asynchronous port forwarding server using only Python standard library (socket, syncope). 为了使用python实现端口转发,有一个很棒的ActriveState配方,只使用Python标准库(套接字,晕厥)来执行异步端口转发服务器。 Look at 看着

http://code.activestate.com/recipes/483732-asynchronous-port-forwarding/ http://code.activestate.com/recipes/483732-asynchronous-port-forwarding/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM