Python UDP通信停滞问题求助:收发数据异常排查
UDP通信接收停滞问题排查求助
我用Python实现UDP数据收发功能,此前已通过Wireshark和UDP测试工具验证需求可行性:与电脑UDP连接的设备会向电脑发送0xFF这类单字节数据,电脑向设备发送的数据也能被正常处理。
但自己写的Python代码存在接收数据问题:虽然能向设备发送数据,但接收时会导致UDP通信停滞(设备和电脑的传输均受影响),只有通过UDP工具发送数据才能恢复通信。附上代码,恳请熟悉Python Socket模块及UDP通信的人士帮忙排查:
import socket sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(("0.0.0.0", 6000)) receiver_ip = "192.168.0.2" reveiver_port = 5000 while True: sock.sendto(bytes([0x11]), (receiver_ip, reveiver_port)) print("Send Data:", ' '.join(f"0x{b:02X}" for b in bytes([0x11]))) data, addr = sock.recvfrom(1) sender_ip, sender_port = addr print("Received Data:", ' '.join(f"0x{b:02X}" for b in data)) print(sender_ip) if data == bytes([0xFF]) and sender_ip == "192.168.0.2" and sender_port == 6000: send_data = bytes([0xAB]) print("Received Data:", ' '.join(f"0x{b:02X}" for b in data)) sock.sendto(send_data, (receiver_ip, reveiver_port)) print("Send Data:", ' '.join(f"0x{b:02X}" for b in bytes([0xAA]))) sock.shutdown()
问题排查与修正建议
核心错误:循环内调用
sock.shutdown()
UDP是无连接协议,shutdown()仅适用于TCP这类面向连接的套接字。在UDP套接字上调用该方法会直接关闭套接字的读写功能,导致后续循环中的收发操作全部失效,这是通信停滞的根本原因,必须删除这行代码。阻塞接收导致假死
sock.recvfrom(1)是阻塞调用,若设备未及时返回数据,代码会一直卡在这一步。可给套接字设置超时避免无限阻塞:sock.settimeout(1) # 根据需求调整超时时间,单位秒配合
try-except捕获socket.timeout异常,让程序可以继续循环执行。端口判断逻辑错误
代码中判断sender_port == 6000,但6000是本地绑定的端口,设备发送数据时使用的是自身的端口(比如代码中写的5000),该条件永远无法成立,导致后续的0xAB数据无法发送。建议确认设备的源端口,或仅通过IP判断设备身份。冗余代码清理
代码中重复打印接收数据的语句可合并,减少冗余输出。
修正后的示例代码
import socket sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(("0.0.0.0", 6000)) sock.settimeout(1) # 设置超时,避免无限阻塞 receiver_ip = "192.168.0.2" receiver_port = 5000 # 修正原代码的拼写错误 while True: # 发送0x11 send_data_11 = bytes([0x11]) sock.sendto(send_data_11, (receiver_ip, receiver_port)) print(f"Send Data: {' '.join(f'0x{b:02X}' for b in send_data_11)}") try: # 尝试接收数据 data, addr = sock.recvfrom(1) sender_ip, sender_port = addr print(f"Received Data: {' '.join(f'0x{b:02X}' for b in data)}") print(f"Sender IP: {sender_ip}") # 仅通过IP判断设备,根据实际情况调整端口判断 if data == bytes([0xFF]) and sender_ip == receiver_ip: send_data_ab = bytes([0xAB]) sock.sendto(send_data_ab, (receiver_ip, receiver_port)) print(f"Send Data: {' '.join(f'0x{b:02X}' for b in send_data_ab)}") except socket.timeout: print("超时未收到数据") # 发送0xAA send_data_aa = bytes([0xAA]) sock.sendto(send_data_aa, (receiver_ip, receiver_port)) print(f"Send Data: {' '.join(f'0x{b:02X}' for b in send_data_aa)}")
内容的提问来源于stack exchange,提问作者ulix
相关产品推荐
相关产品推荐

