如何使用Python实现不同ISP下两台计算机连接与文件传输
跨ISP双机免费互联传视频的Pythonic落地方案
核心原则:完全免费、无付费云服务器依赖、代码符合Pythonic简洁高效的设计风格、专门针对大体积视频文件双向传输场景优化,无冗余功能。
选型逻辑
- 优先走直连链路,不依赖中转服务器,能跑满两端带宽,无流量限制
- 所有依赖组件均为Python生态开源免费组件,无付费门槛
- 逻辑分层做兜底,从最优到最差链路自动切换,无需手动调试复杂配置
- 代码尽量用标准库+成熟轻量第三方包,避免过度封装,可读性和可维护性拉满
具体实现路径
- 第一步:链路探测按优先级自动切换
- 优先探测两端公网IPv6地址:目前国内主流家宽、手机热点基本都已分配公网IPv6,只要两端能拿到IPv6地址,直接走IPv6 TCP直连,零成本、打洞成功率100%
- 无可用IPv6的场景,用公共免费STUN服务探测两端NAT类型和公网UDP映射端口,通过免费公共MQTT broker做信令交换(无需自行搭建信令服务,零成本),交换地址信息后自动做UDP打洞,打洞成功后切TCP链路传文件,90%以上的家宽NAT场景都能打通
- 极端对称NAT场景打洞失败的话,用身边闲置的低功耗设备(比如树莓派、旧手机跑Python脚本)做临时中继,不用额外花钱买云服务器,中继只在打洞失败时启用,平时不占资源
- 第二步:文件传输逻辑(完全Pythonic实现)
遵循Python"直白优于隐晦"的设计原则,不搞花里胡哨的功能,只针对视频传输做核心优化
- 用
asyncio+aiofiles做异步分块读写,单块大小设为1MB,哪怕是几十G的4K视频,也不会占满内存,传输过程不会卡进程 - 内置断点续传逻辑:传文件前先交换两端文件的MD5值和已传输分片大小,传输中断后下次启动直接从断点续传,不用从头重传
- 双向传输无主次:两台设备跑同一份脚本,既可以主动选本地视频推送给对端,也可以自动接收对端发来的文件存到指定目录,没有服务端客户端的强制区分
- 内置轻量AES加密,用
cryptography库实现,传输内容全程加密,不会被链路窃听
- 用
- 第三步:部署方式
- 依赖安装只需要一条命令:
pip install pystun3 paho-mqtt aiofiles cryptography - 脚本写完后可以用
pyinstaller打包成单文件可执行程序,不用在两台电脑上装Python环境,双击就能跑 - 第一次跑只需要填对端唯一识别码、本地文件存储目录两个参数,剩下的链路探测、打洞、连接逻辑全自动运行,不用手动配端口映射
- 依赖安装只需要一条命令:
核心代码片段示例
STUN地址探测代码:
import stun # 探测本地NAT类型和公网映射地址 nat_type, external_ip, external_port = stun.get_ip_info()
信令交换核心代码(用免费公共MQTT服务,无需自建):
import paho.mqtt.client as mqtt import json from uuid import uuid4 PEER_ID = str(uuid4()) TOPIC = "p2p_video_transfer_peers" # 初始化MQTT客户端连接公共服务 client = mqtt.Client(client_id=f"video_transfer_{PEER_ID}") client.connect("public-mqtt-broker", 1883, 60) # 上报自己的连接信息 def report_addr(ip, port): msg = json.dumps({"peer_id": PEER_ID, "ip": ip, "port": port}) client.publish(TOPIC, msg) # 订阅对端上报的地址信息 client.subscribe(TOPIC) client.on_message = lambda client, userdata, msg: handle_peer_msg(json.loads(msg.payload)) client.loop_start()
避坑说明
- 用IPv6直连的时候,记得给Python程序放开系统防火墙的入站权限,不然会被防火墙拦截连接
- 公共STUN、MQTT服务是免费公共资源,只用来做信令交换和地址探测,不要用来跑大流量中继,个人传文件使用完全不会被限流
- 传输大视频的时候不要开VPN类软件,不然会路由错乱导致打洞失败
内容的提问来源于stack exchange,提问作者mrin9san
相关产品推荐
相关产品推荐

