前文中介绍了怎么使用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)
如若二者不同,那只能求诸其他方式;下文中采用的方式亲测有效。
- 首先需要在服务器上安装 ngrok。
或者直接通过命令行安装:
- 获取 ngrok 认证令牌
为了使用 ngrok,你需要注册一个 ngrok 账户并获取认证令牌。登录到 ngrok 后,获取 authtoken(认证令牌)并将其添加到本地配置中。
1 | ngrok config add-authtoken <your-auth-token> |
如此便可以将服务器的 Flask 服务通过 ngrok 隧道暴露到公网,并通过这个 URL 来实现通信。
服务器代码:
1 | from flask import Flask, jsonify, request |
上述代码会有输出:
ngrok tunnel "{public_url}" -> "http://127.0.0.1:5000"
将上述输出的public_url填到下方。(注意/send_data不要遗漏)
客户端代码:
1 | import requests |