基于LwIP的UDP回显服务器创建失败问题求助
LwIP UDP回显服务器创建失败问题解决
问题根源
你遇到的"Error creating UDP pcb"错误,核心原因是LwIP协议栈核心未初始化。udp_new_ip_type函数需要依赖LwIP预先创建的内存池来分配UDP控制块(PCB),直接调用udpecho_raw_init会因内存资源未就绪导致分配失败,返回NULL。此外你的main函数初始化后直接退出,没有运行LwIP的事件循环,即便初始化成功也无法处理网络报文。
必须补充的初始化步骤
需要按顺序调用以下函数完成LwIP初始化:
lwip_init():初始化LwIP核心内存池、协议栈基础模块- 网络接口初始化:创建并激活主机网卡对应的LwIP网络接口(适配Ubuntu环境)
- 启动事件循环:定期调用
sys_check_timeouts()处理LwIP超时任务,同时监听网络事件
修改后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "lwip/opt.h" #include "lwip/udp.h" #include "lwip/ip.h" #include "lwip/netif.h" #include "lwip/sys.h" #include "lwip/tcpip.h" #include "netif/ethernet.h" #include "netif/loopif.h" static struct udp_pcb *udpecho_raw_pcb; static void udpecho_raw_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { LWIP_UNUSED_ARG(arg); printf("udpecho_raw_recv\n"); if (p != NULL) { /* 回显收到的UDP数据 */ printf("udpecho_raw_recv: 收到UDP数据: %s\n", (char *)p->payload); udp_sendto(upcb, p, addr, port); /* 释放pbuf */ pbuf_free(p); } } void udpecho_raw_init(void) { udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); if (udpecho_raw_pcb != NULL) { err_t err; err = udp_bind(udpecho_raw_pcb, IP_ANY_TYPE, 7); if (err == ERR_OK) { udp_recv(udpecho_raw_pcb, udpecho_raw_recv, NULL); printf("UDP回显服务器已启动,监听端口7\n"); } else { printf("udp_bind失败,错误码: %d\n", err); } } else { printf("创建UDP PCB失败\n"); } } /* 网络接口初始化回调 */ static err_t netif_init_cb(struct netif *netif) { netif->flags |= NETIF_FLAG_UP; return ERR_OK; } int main(void) { struct netif netif; ip_addr_t ipaddr, netmask, gw; // 1. 初始化LwIP核心 lwip_init(); // 2. 配置IP地址(根据你的Ubuntu主机网卡信息修改) IP4_ADDR(&ipaddr, 192, 168, 1, 100); IP4_ADDR(&netmask, 255, 255, 255, 0); IP4_ADDR(&gw, 192, 168, 1, 1); // 3. 添加并初始化网络接口(这里用环回接口做测试,也可以替换为真实网卡) netif_add(&netif, &ipaddr, &netmask, &gw, NULL, netif_init_cb, tcpip_input); netif_set_default(&netif); netif_set_up(&netif); // 4. 初始化UDP回显服务器 udpecho_raw_init(); // 5. 启动事件循环,处理LwIP任务 while (1) { sys_check_timeouts(); usleep(10000); // 避免占用过高CPU } return 0; }
额外说明
- 如果你需要绑定真实物理网卡,需要替换
netif_add中的网卡初始化函数(比如对应Linux的tap或tun接口驱动),环回接口仅用于本地测试。 - 端口7是系统保留端口,运行程序需要
sudo权限,否则udp_bind会失败。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

