UDP 套接字收不到数据的分析与解决方法

UDP 套接字收不到数据的分析与解决方法

一、复现场景
        这个问题是做 SIL 维护软件时遇到的。一个板卡给另外一个板卡发送 UDP 报文。发送端板卡和接收端板卡都有三个 UDP 套接字。此时都能正常收发,但是当接收端板卡有两个套接字不 recvfrom 接收数据,导致另外一个套接字也收不到数据。用 tcpdump 抓包能抓到数据。
二、分析流程
        一开始我和大家一样,疯狂加打印。最后定位到协议栈里面recv_udp函数申请netbuf那退出了,并没有按正常逻辑往下走。这个时候就需要梳理一下网卡接收数据上传的逻辑了。
        网卡接收到数据,协议栈会根据不同报文类型调用不同的input任务处理。udp_input 任务最终调用 recv_udp,在这个函数中申请 netbuf,将网卡收到的数据放到 recvmbox 消息队列里,应用程序再从消息队列里面拿数据。所以当一个板卡发 UDP 报文另一个板卡收 UDP 报文,UDP 能够正常通信。
        但消息队列最大长度是 512,netbu f最大数量是 1024个。所以当有两个 UDP 套接字不收数,netbuf 就会被占满导致其他套接字收不到数据。
三、解决方法
        1、修改应用程序代码,一直 recvfrom 收数据,netbuf 用完即释放。
        2、修改 base,将 netbuf 数量改大或者消息队列长度改小(消息队列长度改小如果接收速度慢可能会丢数)。
        修改 netbuf 的头文件在 libsylixos/SylixOS/config/net/ 目录下的 net_perf_cfg.h。第 34 行 LW_CFG_LWIP_MSG_SIZG 为一个套接字最大的消息队列长度,第39行 LW_CFG_LWIP_NUM_NETBUF 为系统总的 netbuf 数量。

    • Related Articles

    • TCP/UDP 通信中 server 端异常关闭后无法再次连接

      Q:在 TCP/UDP 通信中,服务器和客户端正常通信时若手动异常关闭 server 端进程,再次运行开启 server 端程序会在 bind 函数位置报错,造成无法连接? 尝试在 bind 函数前添加 setsockopt 函数增加复用功能,重用本地地址,代码如下  iRet = setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, &iRet, sizeof(int));     if(iRet < 0){         ...
    • SylixOS使用的网络协议栈是?

      Q:SylixOS使用的网络协议栈是? SylixOS使用的网络协议栈是 lwip 版本为 v2.1.0。 /** X.x.x: Major version of the stack */ #define LWIP_VERSION_MAJOR 2 /** x.X.x: Minor version of the stack */ #define LWIP_VERSION_MINOR 1 /** x.x.X: Revision of the stack */ #define ...
    • 【网络攻击】阿基里斯测试仪测试导致协议栈崩溃解决办法

      问:【网络攻击】阿基里斯测试仪测试导致协议栈崩溃解决办法 测试方法: 发送 ip fragment 报文,10M 流量,测试报文一直没有最后一片的标志,就是相当于无限分片。 这些报文先把协议栈 pbuf 全部占满了,一直没有释放,在等最后一片或者超时。 所以在测试过程中,协议栈资源一直是满的,无法提供服务。 分析: ( 由源码可知,协议栈针对这个的超时时间应该是 15s ),如果支持无限分片,资源迟早会消耗光 答:修改IP分片
    • SylixOS 协议栈学习(一)网络接口结构

             1) netif 的结构体来描述一个硬件网络接口的。     struct netif {                                                         struct netif *next;    // 指向下一个 netif 结构的指针         struct ip_addr ip_addr;    // IP 地址相关配置         struct ip_addr netmask;         struct ...
    • nat 命令

      说明 该命令用于启动、关闭或设置NAT虚拟网络地址服务。 格式  nat [stop] | {[LAN Iface] [WAN Iface]} stop :关闭NAT虚拟网络地址服务 LANIface/WANIface:启动NAT虚拟网络地址服务(内网/外网) 可通过shell命令:help nat  查看详细信息 示例  1.启动nat虚拟网络地址服务 en1 为内网 、en2 为外网 [root@sylixos:/root]#nat  en1  en2  2.关闭nat虚拟网络地址服务 ...