| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> Linux中一个网络包的发送/接收流程 -> 正文阅读 |
|
[系统运维]Linux中一个网络包的发送/接收流程 |
图像解析
套接字缓冲区发送队列由一个个struct sk_buff 结构体的链表组成,其中一个sk_buff数据结构对应一个网络包;这个结构体后面会详细讲,是Linux实现网络协议栈的核心数据结构。 IP层 数据链路层/物理层
进行协议头的增添
结构体中存储的是指向内存中各种协议的首部地址的指针,而在发送数据包的过程中,sk_buff中的data指针指向最外层的协议头; 网络包的大小占用 因此当发送这个网络包时: Case1:不存在缓冲区积压,则新建一个sk_buff进行网络包的发送;
Case2:如果缓冲区积压(存在未被ACK的已经发送的网络包-即SEND-Q中存在sk_buff结构),Linux会尝试将当前包合并到SEND-Q的最后一个sk_buff结构中 (粘包) ; 考虑我们上述的768bytes的结构体为SEND-Q的最后一个sk_buff,当用户进程继续调用write系统调用写入2kb的数据时,前一个数据包还未达到MSS/MTU的限制、整个缓冲区的大小未达到SO_SENDBUF指定的限制,会进行包的合并,packet data = 2 + 2,头部的相关信息都可以进行复用,因为套接字缓冲区与套接字是一一对应的;
发送窗口 sk_buff结构中通过sk_wmem_queued标识发送缓冲区已经使用的内存大小,并在发包时检查当前缓冲区大小是否小于SO_SENDBUF指定的大小,如果不满足则阻塞当前线程,进行睡眠,等待发送窗口中有包被ACK后触发内存free的回调函数唤醒后继续尝试发送; 接收窗口(拥塞窗口)
接收窗口主要分为3部分: RCV.USER 为积压的已经收到但尚未被用户进程通过read等系统调用获取的网络数据包;当用户进程获取后窗口的左端会向右移动,并触发回调函数将该数据包的内存free掉; 每个网络包对应的网卡存储在sk_buff结构的dev_input中; RingBuffer队列内存放的是一个个描述符(Descriptor),其有两种状态:ready 和 used。 初始时 Descriptor 是空的,指向一个空的 sk_buff,处在 ready 状态。 PS:如果PageCache中不存在对应的数据页缓存,则需要通过磁盘DMA Copy到内存中。 因此read then write 需要两次系统调用(4次上下文切换,因为系统调用需要将用户态线程切换到内核态线程进行执行),两次CPU Copy、两次DMA Copy。 sendFile 因此sendFile 需要一次系统调用,一次CPU Copy; 相比于write,sendFile少了一次PageCache拷贝到内存的开销,但是需要限制在网络传输的是文件页,而不是用户缓冲区中的匿名页,并且因为完全在内核态进行数据copy,因此无法添加用户态的协议数据; Kafka因为基于操作系统文件系统进行数据存储,并且文件量比较大,因此比较适合通过sendFile进行网络传输的实现; 但是sendFile仍然需要一次内核线程的CPU Copy,因此零拷贝更偏向于无需拷贝用户态空间中的数据。 mmap + write RocketMQ 选择了 mmap+write 这种零拷贝方式,适用于消息这种小块文件的数据持久化和传输。 最后 免费获取源码地址:http://ym.baisouvip.cn/html/wzym/36.html PHP学习手册:https://doc.crmeb.com 技术交流论坛:https://q.crmeb.com |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年4日历 | -2025/4/22 10:30:48- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |