周口网站关键词优化,重庆招商网,哈尔滨工程项目建设网,wordpress英文模板目录 前言
一、UDP广播接收程序
二、异常原因分析
总结 前言 在ubuntu18.04系统中#xff0c;编写udp接收程序发现接收不到广播报文#xff0c;使用抓包工具tcpdump可以抓取到广播报文#xff0c;在此对该现象分析解析如下文所示。 一、UDP广播接收程序 UDP广播接收程序如…
目录 前言
一、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_MAX1.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_filter0
#net.ipv4.conf.all.rp_filter0两项参数解释如下 net.ipv4.conf.default.rp_filter0: 这个设置表示在默认的网络接口上关闭反向路径过滤。反向路径过滤用于验证从系统收到的数据包是否通过与内核期望的相同的网络接口返回。将其设置为0表示禁用反向路径过滤。 net.ipv4.conf.all.rp_filter0: 这个设置表示在所有网络接口上关闭反向路径过滤。与前一个设置不同这个设置应用于系统上的所有网络接口。 由于上位机软件发送该广播报文时并没有绑定源地址且此时ubuntu系统是默认开启源地址验证则该报文则被系统方向过滤掉了。鉴于该种情况在ubuntu系统中关闭反向路径过滤即可如下 重启ubuntu系统在此运行程序时发现recvform可以接收到该广播报文。 总结 在ubuntu系统如果碰到recvform接收不到广播报文的情况可以参考本文内容解决。