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

LWIP IP 报文输入流程详解

LWIP 中 IP 报文的输入处理采用中断 / 轮询接收 + 线程异步处理的模式,核心流程分为:网卡数据读取、报文类型判断、IP 报文转发至 TCP/IP 线程、TCP/IP 线程处理四个阶段。

1. 网卡数据读取与初步处理(ethernetif_input)

ethernetif_input是网卡驱动的输入处理函数,通常在轮询线程或中断回调中被调用,负责从网卡硬件读取数据并进行初步分类。

#include "lwip/netif.h"
#include "lwip/etharp.h"
#include "lwip/ip.h"
#include "lwip/pbuf.h"// 网卡私有数据结构(存储网卡硬件相关状态)
struct ethernetif {struct netif *netif;       // 关联的网络接口// 其他硬件相关成员(如MAC地址、网卡句柄等)uint8_t mac_addr[6];
};/*** 从网卡读取数据并处理* @param netif 网络接口实例*/
static void ethernetif_input(struct netif *netif) {struct ethernetif *ethernetif = netif->state;  // 获取网卡私有数据struct eth_hdr *ethhdr;                        // 以太网帧头struct pbuf *p;                                // 数据缓冲区(LWIP核心数据结构)// 循环读取网卡数据(直到无新数据)while (1) {// 调用底层硬件接口读取数据(由具体网卡驱动实现)p = low_level_input(netif);if (p == NULL) {// 无数据或读取失败,退出循环break;}// 以太网帧头指向pbuf的负载区(pbuf->payload存储实际数据)ethhdr = (struct eth_hdr *)p->payload;// 根据以太网类型字段判断报文类型(网络字节序转主机字节序)switch (htons(ethhdr->type)) {case ETHTYPE_IP:// 1.1 处理IP报文:更新ARP表(记录发送方IP与MAC的映射)etharp_ip_input(netif, p);// 1.2 剥离以太网帧头(将pbuf指针偏移至IP报文起始位置)// 以太网帧头固定14字节(6字节目的MAC+6字节源MAC+2字节类型)if (pbuf_header(p, -(int)sizeof(struct eth_hdr)) != ERR_OK) {// 调整失败,释放pbufpbuf_free(p);break;}// 1.3 调用网络接口的input函数(通常绑定为tcpip_input)// 将IP报文转发至TCP/IP线程处理if (netif->input(p, netif) != ERR_OK) {pbuf_free(p);  // 转发失败,释放资源}break;case ETHTYPE_ARP:// 处理ARP报文(此处省略,仅关注IP流程)etharp_input(netif, p);break;default:// 未知类型,释放pbufpbuf_free(p);break;}}
}/*** 底层硬件数据读取(由具体网卡驱动实现)* @param netif 网络接口实例* @return 包含数据的pbuf,NULL表示无数据*/
static struct pbuf *low_level_input(struct netif *netif) {struct ethernetif *ethernetif = netif->state;struct pbuf *p = NULL;uint16_t len;// 1. 从网卡硬件读取数据长度(伪代码)len = nic_read_data_length(ethernetif->hw_handle);if (len == 0) {return NULL;}// 2. 分配pbuf链(LWIP通过pbuf管理数据缓冲区)p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);if (p == NULL) {// 内存不足,通知网卡丢弃数据nic_discard_data(ethernetif->hw_handle);return NULL;}// 3. 将网卡数据读取到pbuf中(伪代码)if (nic_read_data(ethernetif->hw_handle, p->payload, len) != len) {pbuf_free(p);return NULL;}return p;
}
2. IP 报文转发至 TCP/IP 线程(tcpip_input)

tcpip_input是网络接口的input回调函数,负责将 IP 报文通过消息邮箱(mbox)发送到 TCP/IP 主线程(tcpip_thread),实现接收线程与协议处理线程的解耦

#include "lwip/tcpip.h"
#include "lwip/memp.h"
#include "lwip/sys.h"// TCP/IP线程的全局消息邮箱(由tcpip_init初始化)
static sys_mbox_t mbox = SYS_MBOX_NULL;/*** 将IP报文发送到TCP/IP线程处理* @param p 包含IP报文的pbuf* @param inp 接收报文的网络接口* @return 成功返回ERR_OK,失败返回对应错误码*/
err_t tcpip_input(struct pbuf *p, struct netif *inp) {// 检查邮箱是否初始化if (mbox == SYS_MBOX_NULL) {return ERR_VAL;  // TCP/IP线程未初始化}// 分配TCP/IP消息结构体(存储报文信息)struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);if (msg == NULL) {pbuf_free(p);  // 内存不足,释放pbufreturn ERR_MEM;}// 填充消息内容msg->type = TCPIP_MSG_INPKT;  // 消息类型:IP输入报文msg->msg.inp.p = p;           // 指向IP报文的pbufmsg->msg.inp.netif = inp;     // 接收报文的网络接口// 尝试发送消息到TCP/IP线程的邮箱if (sys_mbox_trypost(mbox, msg) != ERR_OK) {// 发送失败(邮箱满),释放资源memp_free(MEMP_TCPIP_MSG_INPKT, msg);pbuf_free(p);return ERR_MEM;}return ERR_OK;
}
3. TCP/IP 线程处理 IP 报文(tcpip_thread)

tcpip_thread是 LWIP 的协议处理主线程,负责从邮箱中取出消息并调用对应处理函数(IP 层处理入口为ip_input)。

/*** TCP/IP主线程(协议栈核心处理线程)* @param arg 线程参数(通常为邮箱指针)*/
static void tcpip_thread(void *arg) {sys_mbox_t *mbox = (sys_mbox_t *)arg;struct tcpip_msg *msg;while (1) {// 阻塞等待邮箱消息(无消息时休眠)sys_mbox_fetch(*mbox, (void **)&msg);// 根据消息类型处理switch (msg->type) {case TCPIP_MSG_INPKT:// 处理IP输入报文:调用IP层入口函数ip_input(msg->msg.inp.p, msg->msg.inp.netif);// 释放消息结构体(pbuf由ip_input内部处理或释放)memp_free(MEMP_TCPIP_MSG_INPKT, msg);break;// 其他消息类型(如TCP/UDP事件等)省略default:memp_free(MEMP_TCPIP_MSG_INPKT, msg);break;}}
}
4. 关键流程说明
  1. 数据缓冲区管理:使用pbuf结构体封装网络数据,支持链式缓冲区(适应大报文),避免内存拷贝。
  2. 线程安全:通过消息邮箱(sys_mbox)实现接收线程与 TCP/IP 线程的异步通信,避免协议处理与硬件操作的并发冲突。
  3. ARP 表更新:接收 IP 报文时调用etharp_ip_input,自动记录发送方的 IP-MAC 映射,优化后续发送效率。
  4. 协议分层ethernetif_input处理链路层(以太网),tcpip_input负责跨线程转发,ip_input处理网络层(IP),符合 TCP/IP 分层模型。

以上流程完整覆盖了 LWIP 从网卡接收 IP 报文到交付给网络层处理的全过程,核心设计目标是高效、线程安全、低内存占用

http://www.dtcms.com/a/462939.html

相关文章:

  • 照明回路配线长度-连续测量更方便
  • 自学网站开发哪个网站好域名备案和网站备案区别
  • 政务门户网站建设思想河南seo推广公司
  • 上海网站分站建设福建省建筑信息平台
  • 控制板与上位机通讯协议
  • 建立公司网站的目的淘宝作图在哪个网站上做图
  • 家政类网站开发成本锡林浩特网站建设
  • 画品展现手机网站潍坊免费网站制作
  • 做淘宝门头的网站神宜建设公司官网
  • 如何用dw做网站首页合肥大型网站建设
  • 网站怎样做优惠卷青岛当地的做公司网站的
  • 千年游戏智慧:文化的密码
  • 【AI读书系列-01】10秒沟通 --荒木真理子
  • 如何给网站做优化代码教学参考网站建设
  • 网站开发岗位群产品效果图怎么做出来的
  • 汉南网站建设怎么搭建网站
  • Dual Attention Network for Scene Segmentation 学习笔记
  • Linux 命令:umask
  • 蓝桥杯 填字母游戏
  • javascript开发app教程
  • 域名备案怎么关闭网站wordpress 页面下文章列表
  • SQL入门: HAVING用法全解析
  • 做卷闸门网站有用吗微信小程序商城怎样做
  • 买域名建网站价格青海网页设计
  • 大模型激活值所占用的内存与序列长度、模型维度的解析
  • 持续学习(Continual Learning):让AI像人类一样终身成长
  • 手机版网站推荐个人养老保险怎么交
  • kali制作钓鱼网站
  • seo整站优化方法wordpress跟随按钮怎么做
  • 海外建站服务平台涟水建设银行网站