简体   繁体   English

Python:在路由器后面打开一个侦听端口(upnp?)

[英]Python: Open a Listening Port Behind a Router (upnp?)

I've developed an application that is essentially just a little ftp server with the ability to specify which directory you wish to share on startup. 我开发了一个应用程序,它本质上只是一个小的ftp服务器,能够指定您希望在启动时共享的目录。 I'm using ftplib for the server because it's sick easy. 我正在使用ftplib作为服务器,因为它很容易生病。 The only issue I'm having is that if you are behind a router you have to manually forward the ports on your router and I'm finding that it's a little too complicated for my users (aka co-workers/clients). 我唯一的问题是,如果你在路由器后面,你必须手动转发路由器上的端口,我发现它对我的用户(又名同事/客户端)来说有点太复杂了。

So I've been looking for a simple solution to open ports but I'm finding that most APIs are too broad and way over my head. 所以我一直在寻找一个简单的解决方案来打开端口,但我发现大多数API太宽泛而且超出我的想象。 Does someone know of a solution that would be relatively simple to implement? 有人知道一个相对简单的解决方案吗?

Note: It will really only be used on windows although cross-platform compatibility would be welcomed. 注意:它实际上只会在Windows上使用,尽管欢迎跨平台兼容性。 If there is a windows only solution that is simpler then I would opt for that. 如果有一个更简单的Windows解决方案,那么我会选择它。

Thanks! 谢谢!

The protocol you want is called IGD (for Internet Gateway Device) and is based on UPNP. 您想要的协议称为IGD(用于Internet网关设备),并且基于UPNP。 It allows a client program (yours) to discover the router on the network (using UPNP) and then ask it to forward a specific port. 它允许客户端程序(您的)发现网络上的路由器(使用UPNP),然后要求它转发特定端口。

This is supported by most home routers, and the technique is used by a lot of services like BitTorrent or multiPlayer games, bit it's a bit complicated to use or implement. 大多数家用路由器都支持这种技术,而且很多服务都使用这种技术,比如BitTorrent或multiPlayer游戏,使用或实现它有点复杂。 There are several open source libraries that support IGD and one of the simplest one (which is also cross-platform) is " miniupnp ": see http://miniupnp.free.fr/ 有几个支持IGD的开源库,其中一个最简单的(也是跨平台的)是“ miniupnp ”:请参阅http://miniupnp.free.fr/

Simple example for miniupnp. miniupnp的简单示例。 It creates a mapping on the discovered gateway from external port 43210 to the interface connected to port 43210 on the interface connected to the discovered gateway. 它在发现的网关上创建从外部端口43210到连接到已发现网关的接口上连接到端口43210的接口的映射。

import miniupnpc

upnp = miniupnpc.UPnP()

upnp.discoverdelay = 10
upnp.discover()

upnp.selectigd()

port = 43210

# addportmapping(external-port, protocol, internal-host, internal-port, description, remote-host)
upnp.addportmapping(port, 'TCP', upnp.lanaddr, port, 'testing', '')

Looks like there are a few options, one being miniupnp . 看起来有几个选项,一个是miniupnp There are also python bindings for GNUPnP here . 还有用于GNUPnP Python绑定在这里 For windows minupnp will work, or you could go pure python with miranda-upnp . 对于Windows,minupnp可以工作,或者你可以使用miranda-upnp进行纯python。

There is a nice example of the python GNUPnP bindings being used to open ports on a router here . 有蟒蛇GNUPnP绑定被用来在路由器上打开端口的一个很好的例子在这里 In that example the lease time is set to 0, which is unlimited. 在该示例中,租约时间设置为0,这是无限的。 See here for the definition of add_port. 有关add_port的定义,请参见此处

A simple example might be: 一个简单的例子可能是:

#! /usr/bin/python
import gupnp.igd
import glib
from sys import stderr

my_ip = YOUR_IP

igd = gupnp.igd.Simple()
igd.external_ip = None

main = glib.MainLoop()

def mep(igd, proto, eip, erip, port, localip, lport, msg):
    if port == 80:
        igd.external_ip = eip
        main.quit()

def emp(igd, err, proto, ep, lip, lp, msg):
    print >> stderr, "ERR"
    print >> stderr, err, proto, ep, lip, lp, msg
    main.quit()

igd.connect("mapped-external-port", mep)
igd.connect("error-mapping-port", emp)

#igd.add_port("PROTO", EXTERNAL_PORT, INTERNAL_IP, INTERNAL_PORT, LEASE_DURATION_IN_SECONDS, "NAME")
igd.add_port("TCP", 80, my_ip, 8080, 86400, "web")

main.run()

一篇文章解释了如何将Windows IGD COM对象与win32com一起使用。

I looked for this for many days. 我好好看了好几天。 I was unable to install miniupnpc using pip for python 3. 我无法使用pip for python 3安装miniupnpc。

I solved this isue with an implementation found here which will work for python 2. 我解决了这个问题, 这里有一个适用于python 2的实现。

I forked it and make the changes to be used on python 3, you can find it Here 我将它分叉并进行更改以在python 3上使用,你可以在这里找到它

This implementation is by far the simplest I have seen and works well. 到目前为止,这个实现是我见过的最简单的并且运行良好。

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

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