Windows与WSL Ubuntu间Python Socket通信故障求助
跨Windows与WSL Ubuntu的Socket通信故障排查与解决
问题背景
我编写了一套简单的Python Socket通信程序,本地单系统运行正常,但跨Windows客户端与WSL-Ubuntu服务端通信时出现异常。
客户端代码(Windows系统)
#!/usr/bin/env python3 import socket HOST = "172.19.112.1"#"127.0.0.1" # 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(b"Hello, world") data = s.recv(1024) print(f"Received {data!r}")
服务端代码(WSL-Ubuntu系统)
#!/usr/bin/env python3 import socket HOST = "0.0.0.0"#"117.248.124.120"#"127.0.0.1" # Standard loopback interface address (localhost) PORT = 65432 # Port to listen on (non-privileged ports are > 1023) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() conn, addr = s.accept() with conn: print(f"Connected by {addr}") while True: data = conn.recv(1024) if not data: break conn.sendall(data)
故障现象
- 初始连接失败:Ubuntu服务端正常运行,但Windows客户端发起通信时报错:
Traceback (most recent call last): File "C:\Users\system\Desktop\materials-python-sockets-tutorial\echo-client.py", line 9, in <module> s.connect((HOST, PORT)) ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
- 端口代理后收空值:执行端口代理命令后,客户端能建立连接,但收到空返回:
Received b''
执行的端口代理命令:
netsh interface portproxy add v4tov4 listenport=65432 listenaddress=0.0.0.0 connectport=65432 connectaddress=UbuntuIP address
故障原因
初始连接拒绝:
- WSL 2采用独立虚拟网卡,Windows与WSL网络默认隔离,直接用WSL内部IP访问会被拦截;
- Ubuntu防火墙可能未开放65432端口的入站规则,导致连接请求被拒绝。
代理后收空值:
- 端口代理命令中的
connectaddress未替换为真实的WSL内部IP,导致转发失效; - 客户端发送数据后立即调用
recv,可能因网络延迟未等到服务端回包; - 代理转发过程中数据丢失,或服务端未实际收到客户端发送的数据。
- 端口代理命令中的
解决方法
方法一:利用WSL本地端口转发特性
WSL 2默认会将Windows本地端口转发到WSL内部对应端口,直接修改客户端代码的HOST为"127.0.0.1"即可,无需额外配置代理。
方法二:正确配置端口代理与防火墙
- 在WSL-Ubuntu中执行
hostname -I获取真实内部IP(如172.19.112.100); - 以管理员身份在PowerShell中执行正确的代理命令:
netsh interface portproxy add v4tov4 listenport=65432 listenaddress=0.0.0.0 connectport=65432 connectaddress=172.19.112.100
- 开放Ubuntu防火墙端口:
sudo ufw allow 65432/tcp sudo ufw reload
方法三:优化客户端交互逻辑
- 在客户端
sendall后增加短暂延迟,确保服务端有足够时间处理并返回数据:
import time # ... s.sendall(b"Hello, world") time.sleep(0.1) data = s.recv(1024)
- 在服务端
conn.recv后添加打印语句,验证是否收到客户端数据:
data = conn.recv(1024) print(f"Received from client: {data!r}") # ...
内容的提问来源于stack exchange,提问作者Jaffer Wilson
相关产品推荐
相关产品推荐

