Python UDP跨WiFi设备通信故障求助:遇10049错误后卡接收
同一WiFi下Python UDP跨设备通信问题排查与解决
问题概述
作为UDP新手,用Python写了跨设备UDP通信代码,单设备测试正常,但跨设备运行时先出现WinError 10049错误;把两台Windows设备的网络设为私有后错误消失,但现在两端都卡在“接收”状态。
初始代码
服务器代码
import socket # Create a UDP socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Bind the socket to the server address and port server_address = '192.168.1.1' # Replace with the server's IP address server_port = 12345 server_socket.bind((server_address, server_port)) print(f"Server is running on {server_address}:{server_port}") try: while True: # Wait for a message print("\nWaiting to receive a message...") data, address = server_socket.recvfrom(4096) print(f"Received {len(data)} bytes from {address}") print(data.decode()) if data: sent = server_socket.sendto(data, address) print(f"Sent {sent} bytes back to {address}") finally: print("Closing the server socket") server_socket.close()
客户端代码
import socket # Create a UDP socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_address = '192.168.1.2' # Replace with the server's IP address server_port = 12345 try: # Send data message = 'This is the message. It will be echoed back!' print(f"Sending: {message}") sent = client_socket.sendto(message.encode(), (server_address, server_port)) # Receive response print("Waiting to receive") data, server = client_socket.recvfrom(4096) print(f"Received: {data.decode()}") finally: print("Closing the client socket") client_socket.close()
第一个问题:WinError 10049 解决
这个错误的核心原因是绑定了当前设备不存在的IP地址,或者客户端指定的服务器IP错误,解决步骤:
- 服务器端不要硬写固定IP(比如192.168.1.1),改成绑定
0.0.0.0,这样能监听设备上所有网卡的请求,避免IP写错的问题 - 客户端必须填写服务器设备实际的WiFi局域网IP,而不是随便填写的192.168.1.2
- 查局域网IP方法:Windows按Win+R输入
cmd,打开命令提示符后输入ipconfig,找到WiFi适配器下的IPv4地址;Linux/macOS用ifconfig或ip addr找无线网卡的IP
更新后问题:卡在接收状态 解决
改成私有网络后错误消失,但两端卡住,主要是网络连通性或防火墙拦截导致的,按以下步骤排查:
- 验证网络连通性:在客户端设备的命令提示符里ping服务器的IP,比如
ping 192.168.x.x,如果ping不通,说明两台设备不在同一WiFi网段或路由器隔离了设备;如果ping通,继续下一步。 - 配置防火墙:Windows私有网络默认允许部分通信,但UDP端口可能被拦截。可以临时关闭两台设备的防火墙测试,或者手动添加规则:允许Python程序通过防火墙,或者直接开放UDP 12345端口。
- 给客户端添加超时机制:原客户端代码里
recvfrom会无限等待,添加超时能快速判断是否收到回包,避免一直卡住。 - 修正代码细节:服务器绑定
0.0.0.0自动适配当前IP,客户端指定正确的服务器IP并添加超时。
修正后的示例代码
修正版服务器代码
import socket import os # 创建UDP socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 绑定所有可用网卡,避免IP写错 server_address = '0.0.0.0' server_port = 12345 server_socket.bind((server_address, server_port)) # 自动获取当前WiFi的局域网IP并显示 actual_ip = "" if os.name == 'nt': # Windows系统获取WiFi IP import subprocess result = subprocess.run(['ipconfig'], capture_output=True, text=True) for line in result.stdout.split('\n'): if 'IPv4 Address' in line and 'WiFi' in line: actual_ip = line.split(':')[-1].strip() break else: # Linux/macOS系统获取WiFi IP(以wlan0为例,不同设备可能是wlp2s0等) def get_wifi_ip(ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: import fcntl, struct return socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR struct.pack('256s', ifname[:15].encode()) )[20:24]) except: return "无法获取IP" actual_ip = get_wifi_ip('wlan0') print(f"服务器运行在: {actual_ip}:{server_port}") try: while True: print("\n等待接收消息...") data, address = server_socket.recvfrom(4096) print(f"从{address}收到{len(data)}字节数据") print(data.decode()) if data: sent = server_socket.sendto(data, address) print(f"向{address}回发了{sent}字节数据") finally: print("关闭服务器socket") server_socket.close()
修正版客户端代码
import socket # 创建UDP socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 替换成服务器显示的实际局域网IP server_address = '192.168.x.x' server_port = 12345 try: message = '这是测试消息,会被服务器回传!' print(f"发送: {message}") sent = client_socket.sendto(message.encode(), (server_address, server_port)) print("等待接收回包...") # 设置5秒超时,避免无限等待 client_socket.settimeout(5) try: data, server = client_socket.recvfrom(4096) print(f"收到回包: {data.decode()}") except socket.timeout: print("超时:未收到服务器回包,请检查网络或防火墙") finally: print("关闭客户端socket") client_socket.close()
内容的提问来源于stack exchange,提问作者Michael Efraimidis
相关产品推荐
相关产品推荐

