本地网络UDP广播接收失败:Python脚本故障排查求助
问题
本地小型网络包含LTE路由器、管理型交换机、一台Windows主机,以及一台通过UDP广播位置数据的GNSS设备,该设备设置向255.255.255.255:5017发送广播。
在一台双以太网接口的Windows设备上运行以下Python脚本,尝试接收UDP消息并写入文件,但脚本始终触发socket超时。通过Wireshark可确认UDP数据包已发送并到达主机,已添加5017端口UDP允许的防火墙规则,甚至临时关闭防火墙后问题仍存在。
脚本代码:
import os import socket import pynmea2 import datetime from io import StringIO path = "C:\\DataGoesHere\\" IP = " " port = 5017 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(5) sock.bind((IP,port)) while True: today = datetime.date.today().strftime("%Y%m%d") todayfile = f'{today}_GNSS.csv' pathfile = os.sep.join([path, todayfile]) if not os.path.isfile(pathfile): with open(pathfile, 'w') as file: print('Created file: {}'.format(pathfile)) #pass with open(pathfile, 'a') as file: while today==datetime.date.today().strftime("%Y%m%d"): try: data = sock.recv(4096) print(pynmea2.parse(data.decode())) file.write(data.decode()) except socket.timeout: print("Didn't receive data! [Timeout]")
修复方案与排查建议
- 修正绑定的IP地址:当前代码中
IP = " "是无效的空格字符串。在Windows上接收广播数据包,需绑定到0.0.0.0(监听所有可用网卡接口),或绑定到目标网卡的具体本地IP。推荐改为IP = "0.0.0.0",确保套接字能监听所有网卡的5017端口。 - 开启广播接收权限:在Windows环境下,UDP套接字默认可能未启用广播接收,在
sock.bind之前添加以下代码:sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - 排查双网卡的监听范围:由于主机有双以太网接口,广播包可能到达了未被监听的网卡。可以分别将
IP替换为两个网卡的具体IP(如192.168.1.100、10.0.0.5)测试,确认哪个网卡能接收到数据。 - 验证端口监听状态:运行命令
netstat -ano | findstr :5017,检查脚本进程是否真的在监听5017端口。如果未找到对应进程,说明绑定失败,需排查脚本是否有隐藏异常(如目标路径不存在导致的错误被掩盖)。 - 核对Wireshark捕获细节:确认Wireshark捕获到的数据包目标IP为广播地址,且接收网卡是脚本绑定的接口。如果交换机划分了VLAN,需确认广播包已转发到主机所在VLAN;若使用LTE路由器,需检查路由器是否允许广播包在局域网内转发。
- 优化文件写入逻辑:内层
while循环会一直卡在当日文件写入逻辑中,即使日期切换也无法退出,虽不是超时直接原因,但可将日期检查移至每次循环开头,避免嵌套逻辑阻塞。
内容的提问来源于stack exchange,提问作者JustinB
相关产品推荐
相关产品推荐

