【问题标题】:Python Socket to connect over Global Public IP Address通过全球公共 IP 地址连接的 Python 套接字
【发布时间】:2020-10-19 04:56:45
【问题描述】:

我一直在做一个项目,通过 Python 将位于不同位置的计算机连接在一起。最初,在测试时,我使用我的私有 IP 地址(当时我不知道它是私有的)来连接与我在同一网络上的计算机。但是,当我尝试对位于不同位置的不同网络上的计算机执行此操作时,它根本不起作用。

我认为这是因为该程序正在使用我的计算机的本地 IP 地址,该地址只能连接到同一网络上的计算机。这是我的简化程序:

这是我的服务器端脚本:

server = socket.gethostbyname(socket.gethostname()) # 10.128.X.XXX which is the Internal IP
print(server)
port = 5555
clients = 0

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((server, port))

s.listen(2)
print("Waiting for connection...")

while True:
    conn, addr = s.accept()
    print("Connected to: ", addr)

    conn.send(str.encode(f"{clients}"))
    clients += 1

这是我的客户端脚本:

class Network:
    def __init__(self):
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server = "10.128.0.2"
        self.port = 5555
        self.addr = (self.server, self.port)
        self.id = int(self.connect())

    def connect(self):
        self.client.connect(self.addr)
        return self.client.recv(2048).decode()

network = Network()
print(f"Connected as client {network.id}")

现在,当我尝试将私有 IP 地址替换为全局 IP 地址(此处指定:How do I get the external IP of a socket in Python?)时,出现以下错误:

# Getting the Global IP Address

from requests import get
server = get("https://api.ipify.org").text
s.bind((server, port))
OSError: [WinError 10049] The requested address is not valid in its context

我已经尝试了很多关于如何在使用不同网络的不同位置的多台计算机之间进行通信(将少量数据作为字符串传输)的方法,但我还没有真正得到解决方案。有没有办法可以做到这一点?

【问题讨论】:

  • 在服务器中,您始终使用本地 IP,而不是外部 IP。服务器必须绑定到本地网卡(NIC - 网络 Internet 卡)或所有这些(当您使用 0.0.0.0 时)。想要从互联网连接的客户端必须使用外部 IP。客户端连接到外部 IP,即 Internet Provider 路由器的 IP,路由器将其发送/重定向到您的服务器。
  • 那么我该如何让客户端使用外部IP呢?就像在服务器脚本中一样,我说的是s.bind(___),但是在客户端脚本中没有这样的东西。
  • 在服务器中使用s.bind(local_IP, port),在客户端使用s.connect(external_IP, port)
  • 哇哦!非常感谢!它确实奏效了。也许您可以将此作为答案发布,以便我批准!
  • 嗨@BhavyeMathur,你能告诉我你是如何解决这个问题的吗?我正在使用此处推荐的相同技术,但无法连接。它会抛出这个错误: ConnectionRefusedError: [WinError 10061] 无法建立连接,因为目标机器主动拒绝了它

标签: python sockets networking ip-address


【解决方案1】:

在服务器中,您总是使用local IP(它是计算机中一张网卡的IP,或者0.0.0.0使用所有网卡)

s.bind( (local_IP, port) )

# or 

s.bind( ('0.0.0.0', port) ) 

在客户端你使用external IP

s.connect( (external_IP, port) )

外部客户端使用external IP 连接您的 Internet Provider 路由,此路由器知道此 external IP 已分配给您的计算机并将其重定向到您的服务器。

同时本地客户端可以使用local IP与同一台服务器连接。

external_client --> router(externa_IP) --> server(local_IP) <-- local_client

【讨论】:

  • 嗨,furus,我得到了我的 external_IP 并以与您提到的相同的方式使用(服务器中的 local_IP 和客户端中的 externel_IP)但无法连接。你能进一步指导我吗? (我的客户端和服务器都在同一台机器上运行。我只是想在网络外运行客户端之前检查它)。它导致这个错误: ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine主动拒绝了它
  • 由您的 Internet 提供商控制的路由器可能会阻止某些端口 - 这可能是个问题,因为您无法更改其配置。您可以使用不同的端口测试代码 - 尤其是服务器使用的流行端口 - 即。 HTTP 80,HTTPS 443,FTP 22,等等
  • 您可以使用在线工具来检查您的端口在运行服务器时是否可以访问 - 即。 yougetsignal.com/tools/open-portspentest-tools.com/network-vulnerability-scanning/…
  • 在客户端最好使用0.0.0.0以确保它使用所有本地网卡(所有本地IP)
  • 谢谢 furas,我的端口已关闭。我认为端口转发可以解决我的问题。我说的对吗?
猜你喜欢
  • 2016-04-24
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 2020-07-10
  • 2014-03-25
  • 2011-02-04
  • 1970-01-01
  • 2012-07-05
相关资源
最近更新 更多