20

我开发了一个应用程序,它本质上只是一个小型 ftp 服务器,能够指定您希望在启动时共享哪个目录。我将 ftplib 用于服务器,因为它很容易生病。我遇到的唯一问题是,如果你在路由器后面,你必须手动转发路由器上的端口,我发现这对我的用户(也就是同事/客户)来说有点太复杂了。

因此,我一直在寻找一种简单的解决方案来打开端口,但我发现大多数 API 都过于宽泛,超出了我的想象。有人知道实施起来相对简单的解决方案吗?

注意:尽管跨平台兼容性会受到欢迎,但它实际上只会在 Windows 上使用。如果有一个更简单的仅限 Windows 的解决方案,那么我会选择它。

谢谢!

4

5 回答 5

14

miniupnp 的简单示例。它在已发现网关上创建从外部端口 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', '')
于 2016-02-27T05:24:54.103 回答
13

您想要的协议称为 IGD(用于 Internet 网关设备)并且基于 UPNP。它允许客户端程序(您的)发现网络上的路由器(使用 UPNP),然后要求它转发特定端口。

大多数家庭路由器都支持这一点,并且该技术被许多服务(如 BitTorrent 或多人游戏)使用,但使用或实现有点复杂。有几个支持 IGD 的开源库,其中最简单的一个(也是跨平台的)是“ miniupnp ”:参见http://miniupnp.free.fr/

于 2012-05-03T23:08:05.540 回答
4

看起来有几个选项,一个是miniupnp这里还有 GNUPnP 的 python 绑定。对于 windows minupnp 将起作用,或者您可以使用miranda-upnp使用纯 python 。

这里有一个很好的例子,说明 python GNUPnP 绑定用于打开路由器上的端口。在该示例中,租用时间设置为 0,这是无限制的。有关 add_port 的定义,请参见此处

一个简单的例子可能是:

#! /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()
于 2015-02-21T22:37:55.827 回答
2

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

于 2010-12-08T21:03:41.490 回答
0

我找了很多天。我无法使用 pip for python 3 安装 miniupnpc。

我通过在此处找到的适用于 python 2 的实现解决了这个问题。

我对它进行了 fork 并进行了更改以在 python 3 上使用,你可以在这里找到它

这个实现是迄今为止我见过的最简单的并且运行良好。

于 2018-05-01T09:46:04.337 回答