创建可在远程网络上访问的TCP Server



我正在做的一个项目有一个Android应用程序作为前端,一个Python程序作为后端。

我想从Android应用程序发送数据(主要是图像)到Python程序,做一些处理并将结果发送回Android应用程序。

我发现许多教程建议使用python中的socket模块来创建服务器端,但所有教程仅在本地网络上显示服务器(出于测试目的,我也在python中创建了客户端,但稍后将转换为Java)

服务器代码:

from requests import get
import socket
public_ip = get('https://api.ipify.org').text
print('My public IP address is: {}'.format(public_ip))
# getting the hostname by socket.gethostname() method
hostname = socket.gethostname()
# getting the IP address using socket.gethostbyname() method
local_ip = socket.gethostbyname(hostname)
# printing the hostname and ip_address
print(f"Hostname: {hostname}")
print(f"IP Address: {local_ip}")
#
HOST = local_ip
PORT = 80  # Port to listen on (non-privileged ports are > 1023)

with socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024).decode('utf-8')
if not data:
break
conn.sendall(data.encode('utf-8'))

客户端代码:

import socket
HOST = '…'  # I modify it to the server's public IP address, as printed from the server code
PORT = 80  # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
with socket.create_connection((HOST, PORT)) as s:
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', repr(data))

使用上面的代码,如果我尝试使用80以外的任何端口,我得到ConnectionRefusedError: [Errno 111] Connection refused。对于端口80,我得到TimeoutError: [Errno 110] Connection timed out

在这两种情况下,我都尝试从另一个网络上的设备连接。

我试图在Windows CMD中使用ping命令来检查与服务器的连接,并且我得到"连接拒绝消息"。

我知道防火墙是什么可能阻止连接,但我不知道如何绕过它。我在入站规则部分添加了一个新规则(根据其他网站的建议),但无济于事…结果是一样的。

不同网络的远程设备如何建立连接?

提前感谢☺

为了使用TCP套接字连接连接到您的服务器,您需要确保您的服务器可以侦听公共可用IP地址上的端口。

如果外部IP地址直接分配给您的计算机,如果你在那台计算机上运行服务器代码,那么服务器代码打开的TCP端口应该可以在互联网上使用。

然而,在家庭网络中,IP地址通常分配给调制解调器/路由器,而不是将它们直接分配给任何连接的设备。

要查找您的外部IP地址是否直接分配给计算机,您可以使用您的操作系统支持的工具(例如。ipconfig(windows)。如果您可以看到api.ipify.org返回的IP地址,则意味着您的计算机已直接连接。您可以更改代码以使用公开的IP进行连接:

HOST = public_ip

如果这是成功的意味着您的计算机被直接分配了一个外部地址。这是极不可能的。

有几个解决这个问题的方法:

1)配置路由器转发端口配置你的路由器,将所有连接转发到它的外部TCP端口,到你的网络中分配给你的计算机的内部主机。请在您的路由器上查找操作说明。

2)设置远程代理

如果你没有修改路由器设置的权限,你可以设置一个远程代理监听TCP端口。虽然有许多方法可以做到这一点,但最流行的是建立一个远程SSH隧道,为此您需要有一个具有SSH访问权限和外部IP的服务器。执行命令:

ssh -R 80:localhost:8080 root@your-ssh-server-host

你也可以使用第三方服务,在互联网上公开你的私人主机,如:

  • Ngrok (Commercial, with free plans)
  • Localtunnel(开源,可以自托管)

最新更新