Linux环境C++ UDP程序recvfrom函数无法接收数据问题排查求助
问题原因及修复方案
排查方向
- 防火墙规则校验
树莓派端执行sudo ufw status查看防火墙是否开放20016端口的UDP入站规则,未开放的话执行sudo ufw allow 20016/udp添加规则。同时检查Windows端的出站防火墙规则,确认允许对应发送程序的UDP 20016端口流量出站。 - 发送端配置校验
确认Windows发送端的目标IP为树莓派的局域网真实IP,不要误填127.0.0.1(该地址为Windows本地回环地址,数据不会发送到局域网内的树莓派),同时确认发送端的目标端口为20016,未出现大小端配置错误。 - 端口占用校验
树莓派端执行netstat -anu | grep 20016,确认你的程序确实已经监听在0.0.0.0:20016的UDP端口上,没有其他程序占用该端口。 - 网络连通性校验
先在Windows端ping树莓派的IP确认网络连通,再在树莓派上执行sudo tcpdump -i any udp port 20016抓包,运行发送端程序后查看是否有来自Windows IP的UDP包到达:- 能抓到包:说明是代码逻辑问题,继续往下排查
- 抓不到包:说明问题出在发送端或者网络路由层面,优先排查发送端配置
代码层面问题修复
- 重置地址长度参数
recvfrom调用会修改传入的caddr_length参数值,每次循环调用前需要将caddr_length重新赋值为sizeof(clientAddress),避免后续调用参数异常:
while (1) { cout << "receiving data..." << endl; caddr_length = sizeof(clientAddress); // 每次调用前重置长度 int received_bytes = recvfrom(handle, packetData, sizeof(packetData),0, (struct sockaddr*)&clientAddress, &caddr_length); // 后续逻辑不变 }
- 修复代码不规范问题
原有代码中exit未加括号属于语法错误,变长数组char packetData[packetSize]不符合C++标准,建议修改:
#define PACKET_SIZE 36 char packetData[PACKET_SIZE]; // 错误处理部分修改为 if(handle < 0) { perror("socket"); exit(1); } if ( bind( handle, (struct sockaddr*)&serverAddress, sizeof(serverAddress) ) < 0 ) { perror("bind failure"); exit(1); }
内容的提问来源于stack exchange,提问作者Em_
相关产品推荐
相关产品推荐

