ubuntu18-recvfrom接收不到广播报文异常分析

2023-11-10 00:30

本文主要是介绍ubuntu18-recvfrom接收不到广播报文异常分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

前言

一、UDP广播接收程序

二、异常原因分析

总结


前言

        在ubuntu18.04系统中,编写udp接收程序发现接收不到广播报文,使用抓包工具tcpdump可以抓取到广播报文,在此对该现象分析解析如下文所示。

一、UDP广播接收程序

        UDP广播接收程序如下所示,广播发送程序使用上位机向255.255.255.255地址11100端口发送广播报文。

int CreateUdpSocket(int iUdpPort)
{int flag = 1;int err;int iSockFd = 0;short sPort = (short)iUdpPort;struct sockaddr_in tSockAddr;iSockFd = socket(AF_INET, SOCK_DGRAM, 0);if (iSockFd <= 0){printf("[%s]Create local socket Error.\n", __FUNCTION__);return -1;}tSockAddr.sin_family      = AF_INET;tSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);tSockAddr.sin_port        = htons(sPort);err = setsockopt(iSockFd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int));if(err != 0){printf("ERR: setsockopt  socket error. err = %d,errno = %d[%s] port %d\n",err, errno, strerror(errno), iUdpPort);close(iSockFd);return -2;}if (bind(iSockFd, (struct sockaddr*)&tSockAddr, sizeof(struct sockaddr_in)) < 0){printf("ERR:  bind error.\n");close(iSockFd);return -3;}return iSockFd;
}void *StartBroadCastThread(void *arg)
{char acInterface[] = "eth0";int ifindex = 0;int iSocket = -1;int iLen = 10000;int iRet = 0;int iBroadcastIface = -1;int iEthIndex = 0;int iEthNum = 0;int i;unsigned char *pcData = NULL;struct sockaddr_in tSockAddr;int iSockAddrLen = sizeof(tSockAddr);int iRecvLen = 0;short sSendLen = 0;PT_MSG_INFO ptMsg = NULL;T_MSG_BROADCAST_DEV_INFO *ptBroadCastInfo = NULL;//T_ETHNAME_INFO atEthNameInfo[MAX_ETH_NUM];//   T_DEV_NET_INFO *ptNetInfo = NULL;char acBroadcastIface[24];char acTmpBuf[512];int iSessionId = 0;T_ETHNAME_INFO atEthNameInfo[4];iSocket = CreateUdpSocket(MSG_TEST_BROADCAST_PORT);if (iSocket < 0){printf("socket udp failed\n");return NULL;}pcData = (char *)malloc(iLen);if (NULL == pcData){printf("[%s] malloc failed\n", __FUNCTION__);close(iSocket);return NULL;}//ptHead = (PT_MSG_HEAD)pcBuf;while (1){iRecvLen = recvfrom(iSocket, pcData, iLen, 0, (struct sockaddr *)&tSockAddr, (socklen_t*)&iSockAddrLen);if(iRecvLen <= 0){printf("[%s] recvfrom fail, .\n", __FUNCTION__);close(iSocket);free(pcData);return NULL;}if (iRecvLen < 4){printf("iRecvLen = %d\n", iRecvLen);continue;}printf("[%s]recv len %d, magic %d, cmd %d\n", __FUNCTION__, iRecvLen, pcData[0], pcData[1]);if ((pcData[0] == MSG_MAGIC_FLAG) && (pcData[1] == MSG_CLI2SERV_BROADCAST_QUERY)){printf("[%s]%d\n", __FUNCTION__, __LINE__);memset(pcData, 0, iLen);ptMsg = (PT_MSG_INFO)pcData;ptBroadCastInfo = (T_MSG_BROADCAST_DEV_INFO *)ptMsg->acMsgData;/* srand((int)time(0));iSessionId = (int)(300000.0*rand()/(RAND_MAX+1.0));memset(ptBroadCastInfo, 0, sizeof(T_MSG_BROADCAST_DEV_INFO));ptBroadCastInfo->iSessionId = htonl(iSessionId);*/iRet =  ABI_GetDevInfo((char *)ptBroadCastInfo, sizeof(T_MSG_BROADCAST_DEV_INFO));iRet = COMM_GetNetWorkCardNum(&iEthNum, atEthNameInfo);if (iRet < 0){printf("Get None NetWork Card\n");continue;}for (i = 0; i < iEthNum; i++){sSendLen = sizeof(T_MSG_BROADCAST_DEV_INFO);ptMsg->tMsgHead.magic = MSG_MAGIC_FLAG;ptMsg->tMsgHead.cmd = MSG_SERV2CLI_BROADCAST_QUERY_RESP;ptMsg->tMsgHead.sLen = htons(sSendLen);COMM_GetIpAddr(atEthNameInfo[i].acName, ptBroadCastInfo->acIpAddr, sizeof(ptBroadCastInfo->acIpAddr));read_interface(atEthNameInfo[i].acName, &ifindex, NULL, NULL);send_broadcast(ifindex, MSG_TEST_BROADCAST_PORT, ntohs(tSockAddr.sin_port), pcData, sizeof(T_MSG_HEAD) + sSendLen);}   }}close(iSocket);if (pcData){free(pcData);pcData = NULL;}return NULL;
}

使用tcpdump抓包工具可以抓到广播报文:

但是通过recvfrom函数则接收不到该报文。

二、异常原因分析

        考虑到ubuntu可以自带防火墙,但是通过查询ubuntu系统的防火墙功能,发现并没有开启,通过查询相关资料,发现可能跟Linux内核网络参数的设置有关,涉及到反向路径过滤,在/etc/sysctl.conf中有反向路径过滤参数可以设置,两项参数如下所示:

# Uncomment the next two lines to enable Spoof protection (reverse-path filter)
# Turn on Source Address Verification in all interfaces to
# prevent some spoofing attacks
#net.ipv4.conf.default.rp_filter=0
#net.ipv4.conf.all.rp_filter=0

两项参数解释如下:

  1. net.ipv4.conf.default.rp_filter=0: 这个设置表示在默认的网络接口上关闭反向路径过滤。反向路径过滤用于验证从系统收到的数据包是否通过与内核期望的相同的网络接口返回。将其设置为0表示禁用反向路径过滤。

  2. net.ipv4.conf.all.rp_filter=0: 这个设置表示在所有网络接口上关闭反向路径过滤。与前一个设置不同,这个设置应用于系统上的所有网络接口。

        由于上位机软件发送该广播报文时并没有绑定源地址,且此时ubuntu系统是默认开启源地址验证,则该报文则被系统方向过滤掉了。鉴于该种情况,在ubuntu系统中关闭反向路径过滤即可,如下:

重启ubuntu系统,在此运行程序时发现recvform可以接收到该广播报文。


总结

        在ubuntu系统如果碰到recvform接收不到广播报文的情况,可以参考本文内容解决。

这篇关于ubuntu18-recvfrom接收不到广播报文异常分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/379365

相关文章

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Python异常处理之避免try-except滥用的3个核心原则

《Python异常处理之避免try-except滥用的3个核心原则》在Python开发中,异常处理是保证程序健壮性的关键机制,本文结合真实案例与Python核心机制,提炼出避免异常滥用的三大原则,有需... 目录一、精准打击:只捕获可预见的异常类型1.1 通用异常捕获的陷阱1.2 精准捕获的实践方案1.3

Java中最全最基础的IO流概述和简介案例分析

《Java中最全最基础的IO流概述和简介案例分析》JavaIO流用于程序与外部设备的数据交互,分为字节流(InputStream/OutputStream)和字符流(Reader/Writer),处理... 目录IO流简介IO是什么应用场景IO流的分类流的超类类型字节文件流应用简介核心API文件输出流应用文

Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧

《Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧》本文将通过实际代码示例,深入讲解Python函数的基本用法、返回值特性、全局变量修改以及异常处理技巧,感兴趣的朋友跟随小编一起看看... 目录一、python函数定义与调用1.1 基本函数定义1.2 函数调用二、函数返回值详解2.1 有返

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏