无需修改router/firewall,Python实现跨非本地电脑数据传输方案咨询
可行的跨公网数据传输方案(客户端为Python)
由于无法修改路由器/防火墙配置,直接用socket做公网通信会被NAT和防火墙阻断,以下是几种无需修改网络配置的实现方案:
方案1:内网穿透工具(最简单,复用你的socket代码)
用ngrok这类工具把电脑B的内网端口映射到公网,客户端直接连映射后的公网地址即可:
- 在电脑B上运行ngrok:
ngrok tcp 65432,终端会输出类似tcp://0.tcp.ngrok.io:12345的公网地址 - 修改你的Python客户端代码,把
HOST设为0.tcp.ngrok.io,PORT设为12345,服务端代码保持不变
方案2:基于HTTP协议(防火墙默认放行80/443端口)
服务端用HTTP接口接收数据,客户端用Python的requests模块发送请求,无需处理socket穿透问题:
服务端示例(Python Flask)
from flask import Flask, request app = Flask(__name__) @app.route('/upload', methods=['POST']) def save_data(): data = request.data with open("logs.txt", "wb") as log_file: log_file.write(data) return "数据已接收" if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
如果电脑B没有公网IP,同样用ngrok映射5000端口:ngrok http 5000
客户端示例(Python)
import requests input_key = "hi" # 替换为服务端的公网地址或ngrok映射后的地址 server_url = "http://xxx.xxx.xxx.xxx:5000/upload" response = requests.post(server_url, data=str(input_key).encode('utf-8')) print(response.text)
方案3:P2P穿透(无需中转服务器)
用libp2p这类P2P库实现NAT穿透,直接在两台电脑间建立连接:
服务端示例(Python)
from libp2p import new_node import asyncio async def start_server(): node = await new_node() print(f"服务端节点ID: {node.get_id().pretty()}") print(f"服务端地址: {node.get_addrs()[0]}") async def handle_stream(stream): data = await stream.read() with open("logs.txt", "wb") as log_file: log_file.write(data) await stream.close() node.set_stream_handler("/data-transfer/1.0.0", handle_stream) await asyncio.Future() # 保持服务运行 asyncio.run(start_server())
客户端示例(Python)
from libp2p import new_node import asyncio async def send_data(): node = await new_node() # 替换为服务端输出的节点ID和地址 peer_id = "QmXYZ..." peer_addr = "/ip4/xxx.xxx.xxx.xxx/tcp/65432/p2p/QmXYZ..." stream = await node.new_stream(peer_id, ["/data-transfer/1.0.0"]) await stream.write("hi".encode('utf-8')) await stream.close() asyncio.run(send_data())
你提供的原始代码整理:
客户端(echo-client.py)
import socket inputKey = "hi" # Data transferring via sockets HOST = "" # The server's hostname or IP address PORT = 65432 # The port used by the server with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((HOST, PORT)) s.sendall(bytes(str(inputKey), encoding='utf-8'))
服务端
import socket # Data receiving via sockets HOST = "" PORT = 65432 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() connexion, addr = s.accept() with connexion: print(f"Connected by {addr}") while True: data = connexion.recv(1024) if not data: break # printing in logs.txt with open("logs.txt","wb") as log: log.write(data)
内容的提问来源于stack exchange,提问作者Kittynator
相关产品推荐
相关产品推荐

