LWIP udp 回调函数

LWIP udp 收发大包应用

最近因公司一项目需要,udp需一次性接收4K左右的数据,一开始发现Udp_Recv只能接收256BYTE的数据,于是想到了lwipopt.h中缓存池大小的设置,便顺手将缓冲区大小设置到了1500。

//*****************************************************************************
//
// ---------- Pbuf options ----------
//
//*****************************************************************************
#define PBUF_LINK_HLEN                  16          // default is 14
#define PBUF_POOL_BUFSIZE               1500        // 定义单个缓冲区大小
#define ETH_PAD_SIZE                    0           // default is 0

由此便一步步进入误区。(只考虑了单个缓冲区,忘记pbuf链表的后半部分)

后再收发大包数据时发现数据只能在1500BYTE范围内,便方向又跑到了MTU(允许最大传输单元,1500BYTE)的限制中去,一番折腾失败而归,后来发现是自己的Udp_Recv回调函数出了问题,如下:

/*---------------------------------------------------------------------------+
|  Function :                                                                |
|  Task     :                                                                |
+----------------------------------------------------------------------------+
|  Call     :                                                                |
|                                                                            |
|  Parameter:                           -                                    |
|                                                                            |
|  Return   :                           -                                    |
+---------------------------------------------------------------------------*/
static void Udp_Recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
{
    if (p != NULL)
    {
        pcb->remote_ip = *addr;
        pcb->remote_port = port;

        Handle_Recv_DATA(p->payload, p->len);

        pbuf_free(p);
    }
}

错误之处在于误以为(p->payload, p->len)将所有数据带入应用层,后发现只copy了pbuf链表中第一块的数据,也就是前面提到的
#define PBUF_POOL_BUFSIZE 1500 // 定义单个缓冲区大小,这个1500BYTE正好误导我进入了MTU的轨道。

正解:

//*****************************************************************************
//
// ---------- Internal Memory Pool Sizes ----------
//
//*****************************************************************************
#define MEMP_NUM_PBUF                     48    // Default 16
//#define MEMP_NUM_RAW_PCB                4
//#define MEMP_NUM_UDP_PCB                4
#define MEMP_NUM_TCP_PCB                  16    // Default 5
//#define MEMP_NUM_TCP_PCB_LISTEN         8
//#define MEMP_NUM_TCP_SEG                16
//#define MEMP_NUM_REASSDATA              5
//#define MEMP_NUM_ARP_QUEUE              30
//#define MEMP_NUM_IGMP_GROUP             8
#define MEMP_NUM_SYS_TIMEOUT              8
//#define MEMP_NUM_NETBUF                 2
//#define MEMP_NUM_NETCONN                4
//#define MEMP_NUM_TCPIP_MSG_API          8
//#define MEMP_NUM_TCPIP_MSG_INPKT        8
#define PBUF_POOL_SIZE                    16    // Default 16  //缓冲池的个数
//*****************************************************************************
//
// ---------- Pbuf options ----------
//
//*****************************************************************************
#define PBUF_LINK_HLEN                  16          // default is 14
#define PBUF_POOL_BUFSIZE               1500        // 定义单个缓冲区大小
                                                    // default is LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN)
#define ETH_PAD_SIZE                    0           // default is 0

以上的PBUF_POOL_BUFSIZE * PBUF_POOL_SIZE便是缓冲区的总大小,而数据需要从逐个缓存中copy出。
于是回调改为如下:

/*---------------------------------------------------------------------------+
|  Function :                                                                |
|  Task     :                                                                |
+----------------------------------------------------------------------------+
|  Call     :                                                                |
|                                                                            |
|  Parameter:                           -                                    |
|                                                                            |
|  Return   :                           -                                    |
+---------------------------------------------------------------------------*/
static void Udp_Recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
{
	struct pbuf *p_r;
	WORD  u_wRecvLen = 0;

    if (p != NULL)
    {
        pcb->remote_ip = *addr;
        pcb->remote_port = port;

        memset(g_byRecvHMIData, 0, sizeof(g_byRecvHMIData));
        for(p_r = p; p_r != NULL; p_r = p_r->next)
        {
        	memcpy(g_byRecvHMIData+u_wRecvLen, p_r->payload, p_r->len);
        	u_wRecvLen += p_r->len;
        }

        Handle_Recv_DATA(g_byRecvHMIData, u_wRecvLen);

        pbuf_free(p);
    }
}

便可从缓冲区中取出所有数据。

  • 6
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: lwip是一个轻量级的TCP/IP协议栈,非常适合嵌入式系统。在lwip中,UDP是一种基于无连接的协议,它通过IP地址和端口号进行通信。lwip提供了许多UDP例子来帮助开发人员更好地理解和使用UDP协议lwip UDP的示例代码可以在lwip的官方网站上找到。在这些示例中,主要有以下几个方面的内容: 1. 创建UDP服务端:该示例演示如何创建一个UDP服务端,等待客户端发送数据。服务端通过绑定IP地址和端口号来监听UDP数据报。 2. 创建UDP客户端:该示例演示如何创建一个UDP客户端,向服务端发送数据。客户端通过指定服务器的IP地址和端口号来发送UDP数据报。 3. UDP回调函数示例:该示例演示如何使用UDP回调函数处理接收到的UDP数据报。 4. UDP广播示例:该示例演示如何实现UDP广播,将数据发送给局域网中的所有主机。 在使用lwip UDP示例时,需要注意的是,UDP是一种不可靠的协议,所以在数据传输时需要考虑数据的可靠性和完整性。同时,在实际应用中,还需要根据具体需求进行必要的修改和优化。 ### 回答2: lwip是一个轻量级的IP协议栈,提供了TCP、UDP和IP等网络协议协议的支持。lwipUDP例子是基于lwipUDP协议的例子,可以很好地演示lwip实现UDP通信的过程。 lwip实现UDP通信的过程如下: 1. 创建一个UDP协议对象:首先需要通过调用lwip的API(Application Programming Interface)来创建一个UDP协议对象,该对象用于接收和发送UDP数据包。 2. 设置UDP协议对象的参数:在创建UDP对象之后,需要设置UDP协议对象的本地IP地址和端口号等参数,以便实现UDP数据包的接收和发送。 3. 接收UDP数据包:创建UDP对象并设置相关参数后,可以通过API来接收UDP数据包。当有UDP数据包到达时,lwip将其转发给应用程序,应用程序通过API获得UDP数据包的消息内容。 4. 发送UDP数据包:通过API调用来发送UDP数据包,将UDP消息内容和目标IP地址和端口号作为参数传入API中,lwip将此数据包发送到指定的目标地址。 通过以上步骤,就能够很好地实现lwipUDP通信功能,并实现数据交互。在lwipUDP例子中,可以演示如何实现UDP通信功能,具体内容可以参考相关文档和API资料。 ### 回答3: lwip udp example是使用lwip网络协议栈开发UDP协议的示例代码。lwip是一个轻量级的网络协议栈,可以在嵌入式系统中使用,用于实现TCP/IP协议栈。该示例代码可以帮助开发者快速了解如何使用lwip协议栈开发UDP应用程序,并在实际项目中应用。 开发者可以通过lwip udp example学习如何使用lwip协议栈实现UDP通信。示例代码提供了UDP服务器和UDP客户端两种实现方式。开发者可以根据自己的需求选择对应的示例代码,快速构建UDP通信应用程序。示例代码提供了详细的注释,方便开发者理解代码的实现细节。 除了UDP通信示例,lwip还提供了TCP通信示例、DHCP客户端示例、SNMP示例等。开发者可以通过这些示例了解lwip协议栈的各种功能特性,并结合实际项目需求进行定制开发。 总之,lwip udp example是lwip协议栈在UDP应用方面的一个经典示例,可以帮助开发者快速掌握lwip的使用方法,并实际应用于嵌入式项目中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值