【问题标题】:Port forwarding in python to allow socket connectionspython中的端口转发以允许套接字连接
【发布时间】:2016-07-07 11:48:10
【问题描述】:

我使用套接字启动服务器并希望允许客户端连接到它。

self.sock.bind(('0.0.0.0',0)) # 0.0.0.0 will allow all connections and port 0 -> os chooses a open port.
stroke_port=self.sock.getsockname()[1]
self.sock.listen(75)
self.open_port_popup(stroke_port)

现在,为了让其他客户端连接,我手动进行了端口转发,它工作正常。

我想以自动化方式执行此操作。 -> 我试试 upnp。

import miniupnpc

def open_port(port_no):
    '''this function opens a port using upnp'''
    upnp = miniupnpc.UPnP()

    upnp.discoverdelay = 10
    upnp.discover()

    upnp.selectigd()

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

它会打开一个如下图所示的端口。但是第一张图片中显示的端口转发列表是空的。它不起作用,客户端无法连接。我怎样才能解决这个问题?我错过了什么?

【问题讨论】:

  • 本地可以连接吗?
  • @BrianCain 是的,在同一台机器上使用 127.0.0.1。
  • 我认为“第一张图片中的端口转发列表”只显示了手动映射。
  • 至于为什么客户端无法连接,现在由您来诊断:检查网络问题的要点(如果外部端口未打开,则无法在任一方向正确转发数据包,等等。)。如果您的路由器确实是根本原因,那么在 SO 上处理它是题外话。根据stackoverflow.com/questions/4391872/… 的示例,您的程序看起来不错。
  • Upnp 不允许 DHCP 地址,需要路由器上的静态 IP。监听端口是 4000 和 35716 是出端口。您的模块或 UPNP 使用了外部端口(可能是 1900),需要重定向端口以确保安全(保护您的其他本地设备)。不要使用具有默认端口的设备(在 LAN 上)。

标签: python sockets networking


【解决方案1】:

我认为您使用 upnp.lanaddr 作为内部主机地址是错误的。 upnp.lanaddr是你的路由器的upnp设备的地址,你想使用你服务器的本地地址。

如果您想动态获取服务器本地 IP,请查看 Finding local IP addresses using Python's stdlib。

【讨论】:

    【解决方案2】:

    我认为我们缺少很多相关信息来了解这里的主要问题是什么。我看到很多人在猜测。

    顺便说一下,只是编辑那行

    result=upnp.addportmapping(port_no, 'TCP', upnp.lanaddr, port_no, 'testing', '')到

    result=upnp.addportmapping('7777', 'TCP', '192.168.1.8', '7777', 'testing', '') 会告诉你它是否有效。 从 localhost 做端口测试是假的,你根本不在路由器下。

    另外,请记住使用 Try/Except 块来告诉您代码有什么问题。

    try:
        print "1" + 1
    except Exception as e:
        print str(e) 
    

    另一种不成熟的方法是使用 html/web 自动化,甚至 cURL 来发出这些请求,而不是使用 uPnp,这样你就不需要处理它了。

    【讨论】:

      【解决方案3】:

      这是一个有趣的问题。 我想我能召唤出的东西

      GUI 显示添加了 UPNP 端口转发规则。 所以很可能在 UPNPC 配置中存在问题。 我怀疑你是在路由器或类似平台上使用 X-WRT 或 OpenWRT 进行此操作

      我认为的问题是您不能为此使用 upnp,或者由于某些奇怪的原因它不起作用。

      我建议你试试这个库pytables。

      我知道你想知道原因,我正在努力找出原因。

      这只是为了让你继续这个项目

      快速解决方案

      试试这个

       import subprocess
      
      p = subprocess.Popen(["iptables", "-A", "INPUT", "-p", "tcp", "-m", "tcp", "--dport", "22" , "-j", "ACCEPT"], stdout=subprocess.PIPE)
              output , err = p.communicate()
              print output
      

      【讨论】:

      • 嗨,这是我找到的现成代码here。 import subprocess p = subprocess.Popen(["iptables", "-A", "INPUT", "-p", "tcp", "-m", "tcp", "--dport", "22" , "-j", "ACCEPT"], stdout=subprocess.PIPE) output , err = p.communicate() print output
      • 请edit您的答案包括回答问题的代码或其他内容,而不是添加评论。
      • @Devidas 嗨,谢谢回答!我试过你的代码,它给了我这个错误:>>> p = subprocess.Popen(["iptables", "-A", "INPUT", "-p", "tcp", "-m", "tcp", "--dport", "22" , "-j", "ACCEPT"], stdout=subprocess.PIPE) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "c:\Anaconda\lib\subprocess.py", line 710, in __init__ errread, errwrite) File "c:\Anaconda\lib\subprocess.py", line 958, in _execute_child startupinfo) WindowsError: [Error 2] The system cannot find the file specified。如果我遗漏了什么,请告诉我。
      • 我认为我提交的代码假设你有某种 linux 机器。
      • 还有一件事你没有指定平台,所以我很难回答。所以请添加该信息,您是否尝试过 pytables,但从错误中我发现这是 Windows 机器,导致此错误是因为 Windows 上没有名为 iptables 的二进制文件。
      猜你喜欢
      • 2017-12-19
      • 2021-10-13
      • 2020-10-16
      • 1970-01-01
      • 2017-12-25
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      • 2018-09-18
      相关资源
      最近更新 更多