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

简要分析NLMSG_DONE参数

NLMSG_DONE是Linux Netlink协议中用于标记 多部分消息传输结束的标志类型。当内核需要返回大量数据时,会分多个消息块(chunk)发送,最后通过NLMSG_DONE通知用户态“所有数据已发送完毕”。以下是其核心要点:

一、定义与值

  • 头文件:定义在<linux/netlink.h>中:
#define NLMSG_DONE    0x3  /* 多部分消息传输结束 */
  • 作用:标记分块传输的终止,用户态收到此消息后停止等待更多数据。

二、核心作用

1. 分块传输终结符

  • 大数据场景:当内核需返回的数据量较大(如路由表、接口列表等),无法通过单个Netlink消息承载时,会将数据分块发送。
  • 结束标志:最后一个消息块会携带NLMSG_DONE,告知用户态无需继续等待后续数据。

2. 流式传输控制

  • 资源优化:避免一次性分配超大内存,降低内核和用户态的内存压力。
  • 可靠性:若传输中途发生错误,用户态可通过未收到NLMSG_DONE判断数据不完整。

三、数据结构

NLMSG_DONE消息的负载(Payload)通常 为空,仅通过消息头标记结束:
struct nlmsghdr {
    __u32 nlmsg_len;    // 消息总长度(头 + 负载)
    __u16 nlmsg_type;   // 消息类型(此处为 NLMSG_DONE)
    __u16 nlmsg_flags;  // 标志位(如 NLM_F_MULTI)
    __u32 nlmsg_seq;    // 序列号(与请求匹配)
    __u32 nlmsg_pid;    // 发送方端口 ID
};
  • 关键字段:
    • nlmsg_type:设为NLMSG_DONE。
    • nlmsg_flags:若消息分块传输,需包含NLM_F_MULTI标志

四、使用场景示例

1. 用户态接收分块数据

用户态循环接收数据,直到检测到NLMSG_DONE:
while (1) {
    // 接收消息
    len = recv(fd, buf, sizeof(buf), 0);
    struct nlmsghdr *nlh = (struct nlmsghdr *)buf;

    // 遍历消息链(可能多个消息粘包)
    for (; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) {
        if (nlh->nlmsg_type == NLMSG_DONE) {
            printf("所有数据接收完毕\n");
            return 0;
        }
        // 处理其他消息(如 NLMSG_ERROR 或实际数据)
    }
}

2. 内核发送分块数据

内核分块发送数据,最后发送NLMSG_DONE:
// 内核模块代码示例
void send_chunked_data(struct sk_buff *skb, u32 portid) {
    // 分块发送数据
    for (int i = 0; i < total_chunks; i++) {
        struct sk_buff *chunk = alloc_skb(...);
        struct nlmsghdr *nlh = nlmsg_put(chunk, portid, seq, NLMSG_DONE, 0, NLM_F_MULTI);
        // 填充数据到 chunk
        netlink_unicast(nl_sk, chunk, portid, 0);
    }

    // 最后发送 NLMSG_DONE 结束
    struct sk_buff *done_skb = nlmsg_new(0, GFP_KERNEL);
    struct nlmsghdr *done_nlh = nlmsg_put(done_skb, portid, seq, NLMSG_DONE, 0, 0);
    netlink_unicast(nl_sk, done_skb, portid, 0);
}

五、与其他消息类型的区别

消息类型

作用

NLMSG_DONE

3

多部分消息结束标志,无负载数据。

NLMSG_ERROR

2

错误响应或 ACK 确认,携带错误码或成功标志(

error=0

)。

NLMSG_NOOP

1

空操作,无实际行为。

NLM_F_MULTI

-

标志位(非消息类型),表示消息是分块传输的一部分。

六、注意事项

  • 负载数据:NLMSG_DONE通常不携带负载数据(nlmsg_len = sizeof(struct nlmsghdr))
  • 标志位:
    • 分块传输时,除最后一个消息外,其他消息需设置NLM_F_MULTI
    • NLMSG_DONE消息本身不设置NLM_F_MULTI
  • 序列号:所有分块消息和NLMSG_DONE需使用相同的nlmsg_seq,以匹配原始请求

七、总结

  • 本质:Netlink协议中用于标记分块数据传输结束的标志。
  • 用途:
    • 通知用户态分块数据已全部发送完毕。
    • 优化大数据传输的内存和可靠性。
  • 关键行为:
    • 分块消息需设置NLM_F_MULTI
    • 最后一个消息为NLMSG_DONE,不携带负载

相关文章:

  • Ubuntu下升级node.js从12.22到22.14
  • 商业智能BI分析中,汽车4S销售行业的返厂频次有什么分析价值?
  • 查看IP地址/Ping 命令
  • TX-LCN 框架
  • Couchbase Analytics 页面右侧的“Analytics Scopes, Links, Collections”等的解释
  • 在 ARM 嵌入式 Linux 下使用 C/C++ 实现 MQTT
  • HCIA-Access V2.5_14_3_1系统基本操作_管理操作用户
  • RxSwift 学习笔记第四篇之RxSwift在项目中的简单应用
  • Unix时间戳BKP备份寄存器RTC实时时钟
  • C# 不同框架如何调用framework 和 net core
  • 蓝桥杯 刷题统计
  • Vue:添加响应式数据
  • Mysql中创建表时的约束条件
  • 使用Dependency Walker和Beyond Compare快速排查dll动态库损坏或被篡改的问题
  • JavaScript如何做类型转换
  • Python文字识别OCR
  • 麒麟服务器操作系统QT系列软件工具手册
  • 双指针算法-day11(双序列双指针)
  • 用hexo初始化博客执行hexo init时碰到的问题
  • 【即插即用涨点模块】EGA边缘引导注意力:有效保留高频边缘信息,提升分割精度,助力高效涨点【附源码+注释】
  • 时隔4年多,这一次普京和泽连斯基能见面吗?
  • 技术派|更强的带刀侍卫:从054B型战舰谈谈世界护卫舰发展
  • 多家中小银行存款利率迈入“1时代”
  • 中国目的地·入境游简报006|外国网红游中国启示录
  • 泽连斯基:乌克兰已做好与俄罗斯举行会谈的准备
  • 年轻小将绽放光芒!中国短跑男女接力队直通东京世锦赛