Python:在路由器后打开监听端口(upnp?)

23 投票
5 回答
17600 浏览
提问于 2025-04-16 08:15

我开发了一个应用程序,基本上就是一个小型的FTP服务器,可以在启动时指定要共享的目录。我使用了ftplib来搭建这个服务器,因为它非常简单。现在唯一的问题是,如果你在路由器后面,就需要手动在路由器上转发端口,而我发现这对我的用户(也就是我的同事和客户)来说有点复杂。

所以我一直在寻找一个简单的解决方案来打开端口,但我发现大多数API都太复杂了,我根本搞不懂。有没有人知道一个相对简单的解决方案可以实现呢?

注意:这个应用主要是在Windows上使用,虽然如果能跨平台兼容那就更好了。如果有一个仅适用于Windows的更简单的解决方案,我会更倾向于选择那个。

谢谢!

5 个回答

4

看起来有几个选择,其中一个是 miniupnp。还有 GNUPnP 的 Python 绑定,可以在这里找到。如果你使用 Windows,miniupnp 可以正常工作,或者你也可以选择纯 Python 的 miranda-upnp

这里有一个很好的例子,展示了如何使用 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()
13

你想要的协议叫做IGD(互联网网关设备),它是基于UPNP的。这个协议可以让你的程序找到网络上的路由器(通过UPNP),然后请求路由器转发一个特定的端口。

大多数家用路由器都支持这个功能,很多服务,比如BitTorrent或者多人游戏,也会用到这个技术。不过,使用或实现起来有点复杂。有几个开源库支持IGD,其中一个最简单的(而且可以在不同平台上使用)是miniupnp:你可以查看 http://miniupnp.free.fr/

15

这是一个关于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', '')

撰写回答