计算机如何通信(不同局域网下)

前文中介绍了怎么使用socket在相同局域网下通信,接下来介绍在不同局域网下如何通信。

这个问题的源头在于IP,在路由器下的主机并没有实际的公网IP,而是一般由数据传输到有公网IP的路由器,再由路由器根据内网IP与主机通信。这种时候,需要使用端口映射等手段,实现主机的内网穿透。

更为麻烦的情况,是路由器的IP也不是公网IP,而是网络运营商提供的内网IP,端口映射方法也无法生效。

公网IP和WAN口的IP相同(端口映射)

当两IP相同时,可使用端口映射的方式实现Socket通信。

供应商为了节省公网IP,有时会分配一个内网IP给你,这个IP会分配到路由器的WAN口上。

WAN口IP:登录路由器(浏览器输入192.168.1.1或192.168.0.0),可查看WAN口IP。

公网IP:百度搜索IP,可在网页中查看到公网IP。

如若二者一致,则可通过端口映射的方式,完成通信。

在路由器管理界面的NAT设置处找到 端口映射 或者 虚拟服务器 设置。

服务器与客户端代码输出

如上图,将对应WAN口下主机的内网IP和想使用的端口输入内部服务器IP和内部端口,外部端口尽量选择一个9000以上的数字。

如此,就实现了将路由器公网IP的端口映射到局域网下对应端口的操作。

此时的服务器与客户端代码:

1
socket_server.bind(("内网IP", 内部端口))
1
socket_client.connect(("公网IP", 外部端口))

代码详见上一节;

由此可实现通信。

公网IP和WAN口的IP不同(ngrok)

如若二者不同,那只能求诸其他方式;下文中采用的方式亲测有效。

  1. 首先需要在服务器上安装 ngrok。

或者直接通过命令行安装:

  1. 获取 ngrok 认证令牌
    为了使用 ngrok,你需要注册一个 ngrok 账户并获取认证令牌。登录到 ngrok 后,获取 authtoken(认证令牌)并将其添加到本地配置中。
1
$ ngrok config add-authtoken <your-auth-token>

如此便可以将服务器的 Flask 服务通过 ngrok 隧道暴露到公网,并通过这个 URL 来实现通信。

服务器代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from flask import Flask, jsonify, request
from pyngrok import ngrok

app = Flask(__name__)

@app.route('/send_data', methods=['POST'])
def send_data():
data = request.json
print(f"Received data from B: {data}")
return jsonify({"status": "success", "received_data": data})

if __name__ == '__main__':
# 启动 ngrok 隧道,将本地的 5000 端口暴露到公网
public_url = ngrok.connect(30005)
print(f" * ngrok tunnel \"{public_url}\" -> \"http://127.0.0.1:5000\"")

# 启动 Flask 服务
app.run(port=30005)

上述代码会有输出:

ngrok tunnel "{public_url}" -> "http://127.0.0.1:5000"

将上述输出的public_url填到下方。(注意/send_data不要遗漏)

客户端代码:

1
2
3
4
5
6
7
8
9
10
import requests

# 电脑 A 暴露的 ngrok URL
url = "public_url/send_data"

# 向电脑 A 发送 POST 请求
response = requests.post(url, json={"message": "Hello from B!"})

# 打印返回的结果
print("Response from A:", response.json())