当前位置: 首页 > news >正文

RAW API 的 UDP 总结1

主要内容参照17. 使用RAW API接口编程 — [野火]LwIP应用开发实战指南—基于野火STM32 文档,整理出来自用。

1.1 新建控制块:udp_new()

UDP 通信的第一步是创建 UDP 控制块,它是存储 UDP 通信相关信息的核心结构,无控制块则无法进行后续通信。

核心功能

  1. 从内存池(MEMP_UDP_PCB类型)中申请一块内存,用于存放 UDP 控制块;
  2. 若内存申请成功,将控制块所有字段初始化为 0,并设置默认生存时间(ttl = UDP_TTL);
  3. 返回申请到的控制块指针(失败则返回NULL)。

关键说明

  • 控制块是 UDP 通信的 “唯一标识载体”,后续绑定、收发数据均依赖此结构;
  • 函数内通过LWIP_ASSERT_CORE_LOCKED()确保操作在核心锁保护下进行,保证线程安全。

1.2 绑定控制块:udp_bind()

绑定的本质是将 “本机 IP 地址 + 端口号” 与 UDP 控制块关联,使控制块对应唯一应用,确保 UDP 报文能被正确识别并递交到应用层。

核心功能

  1. IP 地址处理:若传入的ipaddrNULL,自动绑定到 “任意 IP 地址”(IP4_ADDR_ANY);
  2. 端口号处理
    • 若端口号为 0,调用udp_new_port()随机分配一个未占用的端口;
    • 若端口号非 0,检查udp_pcbs链表(存储所有 UDP 控制块),确保端口未被其他控制块占用(避免冲突);
  3. 初始化与入链表:将 “本机 IP + 端口号” 写入控制块的local_iplocal_port字段,若控制块未在udp_pcbs链表中,则将其插入链表。

关键说明

  • 绑定是 UDP 接收报文的前提:无绑定端口的控制块无法接收报文(无法识别报文归属);
  • 函数返回ERR_OK表示绑定成功,返回ERR_USE表示端口已占用或无可用端口。

1.3 建立会话:udp_connect()

UDP 是无连接协议,不存在 TCP 式的 “三次握手”,此处 “建立会话” 仅为设置控制块的 “远端 IP + 端口号”,明确数据发送的目标地址。

核心功能

  1. 前置检查:若控制块未绑定 “本机 IP + 端口号”(local_port == 0),自动调用udp_bind()完成绑定;
  2. 设置远端信息:将传入的远端 IP、端口号分别写入控制块的remote_ipremote_port字段;
  3. 标记会话状态:设置控制块标志位UDP_FLAGS_CONNECTED,表示进入 “会话状态”;
  4. 入链表校验:检查控制块是否已在udp_pcbs链表中,未在则插入链表首部。

关键说明

  • 会话建立仅 “本地记录远端信息”,不向远端发送任何连接请求(区别于 TCP);
  • 进入会话状态后,调用udp_send()发送数据时无需重复指定远端地址(直接使用控制块中记录的信息)。

1.4 断开会话:udp_disconnect()

udp_connect()功能相反,用于清除控制块中的远端信息,取消 “会话状态”,但不释放控制块内存

核心功能

  1. 清除远端信息:将控制块的remote_ip设为 “任意地址”、remote_port设为 0、netif_idx设为NETIF_NO_INDEX
  2. 取消会话状态:通过udp_clear_flags()清除UDP_FLAGS_CONNECTED标志位。

关键提示

  • 断开会话仅重置控制块的远端配置,控制块仍存在于udp_pcbs链表中,可重新通过udp_connect()建立新会话;
  • 函数无返回值,仅需传入待处理的控制块指针。

1.5 接收数据:udp_recv()

该函数并非直接接收数据,而是设置数据接收的 “回调桥梁”,让内核在接收到 UDP 报文后,能通过回调函数将数据递交给应用层。

核心功能

  1. 定义回调函数类型udp_recv_fn类型回调函数需包含 4 个参数:
    • void *arg:用户自定义参数;
    • struct udp_pcb *pcb:接收数据对应的 UDP 控制块;
    • struct pbuf *p:存储接收数据的缓冲区(pbuf为 LWIP 的通用数据缓冲区结构);
    • const ip_addr_t *addr/u16_t port:发送方的 IP 地址和端口号;
  2. 绑定回调函数:将传入的回调函数指针recv和用户参数recv_arg,分别赋值给控制块的recvrecv_arg字段。

关键说明

  • 回调函数是 “内核→应用层” 的数据通道:内核接收到 UDP 报文后,会匹配对应的控制块,再调用其绑定的recv函数传递数据;
  • 若未设置回调函数,内核无法将接收的 UDP 报文递交给应用层。

1.6 发送数据:udp_send()udp_sendto()

两者均用于发送 UDP 数据,最终都依赖 IP 层和链路层完成报文封装,核心区别是 “是否需要指定远端地址”。

共同流程

  1. 数据需先封装为pbuf结构,且pbuf需预留 UDP、IP、以太网首部的空间;
  2. 函数内部会填充 UDP 首部,形成完整 UDP 报文后递交给 IP 层;
  3. IP 层添加 IP 首部后递交给链路层,链路层添加以太网首部后发送。

功能差异与核心逻辑

函数适用场景核心逻辑
udp_send()已通过udp_connect()建立会话的场景直接使用控制块中remote_ipremote_port作为目标地址,若未设置远端信息则返回ERR_VAL,最终调用udp_sendto()发送;
udp_sendto()未建立会话 / 需动态指定目标地址的场景需手动传入目标 IP(dst_ip)和端口(dst_port),先通过ip_route()找到合适的网卡(netif),再调用udp_sendto_if()完成发送;

关键说明

  • 若未找到合适的发送网卡(netif == NULL),返回ERR_RTE(路由错误);
  • 两者均返回ERR_OK表示发送成功,返回ERR_VAL表示参数不合法(如 IP 版本不匹配)。

1.7 删除 UDP 控制块:udp_remove()

当 UDP 通信结束后,需通过此函数彻底删除控制块,释放占用的内存资源,避免内存泄漏。

核心功能

  1. 解绑与链表删除
    • 调用mib2_udp_unbind()取消控制块的绑定状态;
    • 若控制块在udp_pcbs链表首部,直接将链表头指向udp_pcbs->next
    • 若控制块在链表中间 / 尾部,遍历链表找到其前驱节点,将前驱节点的next指向当前控制块的next,实现链表移除;
  2. 内存释放:通过memp_free()释放控制块占用的MEMP_UDP_PCB类型内存。

关键说明

  • 控制块删除后无法复用,若需重新通信,需通过udp_new()重新创建控制块;
  • 函数无返回值,操作前需确保控制块指针非空(函数内通过LWIP_ERROR校验)。
http://www.dtcms.com/a/350945.html

相关文章:

  • Android Glide常见问题解决方案:从图片加载到内存优化
  • [在实践中学习] 中间件理论和方法--Redis
  • 【JavaEE】了解volatile和wait、notify(三)
  • 08-引入AI编程插件(TRAE)编写单元测试并检查覆盖率
  • Cloudflare 推出 GenAI 安全工具,守护企业数据
  • 科普 | 5G支持的WWC架构是个啥(1)?
  • android 改机系列之-虚拟摄像头-替换相机预览画面
  • excel导出,多列合并表头
  • 运行node18报错
  • 【JVM】类加载器都有哪些?
  • ChromaDB向量数据库Python教程:从入门到实战完整指南(含游戏资源管理系统案例
  • Java大厂面试实战:从Spring Boot到微服务架构的全链路技术拆解
  • 计算机视觉:从 “看见” 到 “理解”,解锁机器感知世界的密码
  • Windows 命令行:mkdir 命令
  • 【配置】CurSor使用Claude 4.0如何解除地域限制
  • [CS创世SD NAND征文] CS创世CSNP1GCR01-AOW在运动控制卡中的高可靠应用
  • 塞尔达传说 旷野之息 PC/手机双端(The Legend of Zelda: Breath of the Wild)免安装中文版
  • 深入了解linux系统—— 线程封装
  • podman启动mongdb的container因为权限问题导致changing ownership和读取storage.bson失败的解决方法
  • HarmonyOS image组件深度解析:多场景应用与性能优化指南(2.4详细解析,完整见uniapp官网)
  • week5-[循环结构]听歌
  • MAE——Masked Autoencoders Are Scalable Vision Learners/图像分类和去雨雾重建/
  • 【ElasticSearch】json查询语法
  • 每日一题——力扣498 对角线遍历
  • Mo 人工智能在线教学实训平台
  • Python训练营打卡Day43-Tensorboard使用介绍
  • 美团一面“保持好奇”
  • JavaScript 中类(class)的super 关键字
  • AMH和cyberpanel等管理软件,哪个里面可以部署AI软件?
  • 【STM32】CubeMX(十二):FreeRTOS消息队列