Linux网络栈
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11394930.html
OSI模型
OSI 模型把网络互联的框架分为应用层、表示层、会话层、传输层、网络层、数据链路层以及物理层等七层,每个层负责不同的功能。其中,
应用层,负责为应用程序提供统一的接口。
表示层,负责把数据转换成兼容接收系统的格式。
会话层,负责维护计算机之间的通信连接。
传输层,负责为数据加上传输表头,形成数据包。
网络层,负责数据的路由和转发。
数据链路层,负责MAC寻址、错误侦测和改错。
物理层,负责在物理网络中传输数据帧。
TCP/IP 模型
TCP/IP 模型把网络互联的框架分为应用层、传输层、网络层、网络接口层等四层,其中,
应用层,负责向用户提供一组应用程序,比如 HTTP、FTP、DNS 等。
传输层,负责端到端的通信,比如 TCP、UDP 等。
网络层,负责网络包的封装、寻址和路由,比如 IP、ICMP 等。
网络接口层,负责网络包在物理网络中的传输,比如 MAC 寻址、错误侦测以及通过网卡传输网络帧等。
OSI 模型 与 TCP/IP 模型 的关系
Linux网络栈
有了 TCP/IP 模型后,在进行网络传输时,数据包就会按照协议栈,对上一层发来的数据进行逐层处理;然后封装上该层的协议头,再发送给下一层。
当然,网络包在每一层的处理逻辑,都取决于各层采用的网络协议。比如在应用层,一个提供 REST API 的应用,可以使用 HTTP 协议,把它需要传输的 JSON 数据封装到 HTTP 协议中,然后向下传递给 TCP 层。
而封装做的事情就很简单了,只是在原来的负载前后,增加固定格式的元数据,原始的负载数据并不会被修改。比如,以通过 TCP 协议通信的网络包为例,通过下面这张图,可以看到,应用程序数据在每个层的封装格式。
其中:
- 传输层在应用程序数据前面增加了 TCP 头;
- 网络层在 TCP 数据包前增加了 IP 头;
- 而网络接口层,又在 IP 数据包前后分别增加了帧头和帧尾。
这些新增的头部和尾部,都按照特定的协议格式填充,这些新增的头部和尾部,增加了网络包的大小,但物理链路中并不能传输任意大小的数据包。网络接口配置的最大传输单元(MTU),就规定了最大的 IP 包大小。在最常用的以太网中,MTU 默认值是 1500(这也是 Linux 的默认值)。
一旦网络包超过 MTU 的大小,就会在网络层分片,以保证分片后的 IP 包不大于MTU 值。显然,MTU 越大,需要的分包也就越少,网络吞吐能力就越好。
理解了 TCP/IP 网络模型和网络包的封装原理后,很容易能想到,Linux 内核中的网络栈,其实也类似于 TCP/IP 的四层结构。如下图所示,就是 Linux 通用 IP 网络栈的示意图:
从上到下来看这个网络栈,可以发现,
- 最上层的应用程序,需要通过系统调用,来跟套接字接口进行交互;
- 套接字的下面,就是前面提到的传输层、网络层和网络接口层;
- 最底层,则是网卡驱动程序以及物理网卡设备。
网卡是发送和接收网络包的基本设备。在系统启动过程中,网卡通过内核中的网卡驱动程序注册到系统中。而在网络收发过程中,内核通过中断跟网卡进行交互。
再结合前面提到的 Linux 网络栈,可以看出,网络包的处理非常复杂。所以,网卡硬中断只处理最核心的网卡数据读取或发送,而协议栈中的大部分逻辑,都会放到软中断中处理。
Linux网络收发流程
了解了 Linux 网络栈后,再来看看, Linux 到底是怎么收发网络包的。
注意,以下内容都以物理网卡为例。事实上,Linux 还支持众多的虚拟网络设备,而它们的网络收发流程会有一些差别。
网络包的接收流程
先来看网络包的接收流程。
当一个网络帧到达网卡后,网卡会通过 DMA 方式,把这个网络包放到收包队列中;然后通过硬中断,告诉中断处理程序已经收到了网络包。
接着,网卡中断处理程序会为网络帧分配内核数据结构(sk_buff),并将其拷贝到 sk_buff 缓冲区中;然后再通过软中断,通知内核收到了新的网络帧。
接下来,内核协议栈从缓冲区中取出网络帧,并通过网络协议栈,从下到上逐层处理这个网络帧。比如,
- 在链路层检查报文的合法性,找出上层协议的类型(比如 IPv4 还是 IPv6),再去掉帧头、帧尾,然后交给网络层。
- 网络层取出 IP 头,判断网络包下一步的走向,比如是交给上层处理还是转发。当网络层确认这个包是要发送到本机后,就会取出上层协议的类型(比如 TCP 还是 UDP),去掉 IP 头,再交给传输层处理。
- 传输层取出 TCP 头或者 UDP 头后,根据 <源 IP、源端口、目的 IP、目的端口> 四元组作为标识,找出对应的 Socket,并把数据拷贝到Socket 的接收缓存中。
最后,应用程序就可以使用 Socket 接口,读取到新接收到的数据了。
为了更清晰表示这个流程,参考下图,这张图的左半部分表示接收流程,而图中的粉色箭头则表示网络包的处理路径。
网络包的发送流程
了解网络包的接收流程后,就很容易理解网络包的发送流程。网络包的发送流程就是上图的右半部分,很容易发现,网络包的发送方向,正好跟接收方向相反。
- 首先,应用程序调用 Socket API(比如 sendmsg)发送网络包。
- 由于这是一个系统调用,所以会陷入到内核态的套接字层中。套接字层会把数据包放到 Socket 发送缓冲区中。
- 接下来,网络协议栈从 Socket 发送缓冲区中,取出数据包;再按照 TCP/IP 栈,从上到下逐层处理。比如,传输层和网络层,分别为其增加TCP 头和 IP 头,执行路由查找确认下一跳的 IP,并按照 MTU 大小进行分片。
- 分片后的网络包,再送到网络接口层,进行物理地址寻址,以找到下一跳的 MAC 地址。然后添加帧头和帧尾,放到发包队列中。这一切完成后,会有软中断通知驱动程序:发包队列中有新的网络帧需要发送。
- 最后,驱动程序通过 DMA ,从发包队列中读出网络帧,并通过物理网卡把它发送出去。
Reference
https://time.geekbang.org/column/article/80898 (强烈推荐读者购买此专栏,都是干货价值一个亿)
Linux网络栈的更多相关文章
- 理解 Linux 网络栈(3):QEMU/KVM + VxLAN 环境下的 Segmentation Offloading 技术(发送端)
本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...
- 理解 Linux 网络栈(2):非虚拟化Linux 环境中的 Segmentation Offloading 技术
本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...
- 理解 Linux 网络栈(1):Linux 网络协议栈简单总结
本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...
- linux 网络栈中的queueing
这篇文章详细描述了在linux网络栈中queueing,及各种保证系统吞吐量和低延迟的方法机制.
- Linux 网络栈 转载
此文章 来自 http://arthurchiao.art/blog/tuning-stack-rx-zh/ [译] Linux 网络栈监控和调优:接收数据(2016) Published ...
- 扩展Linux网络栈
扩展Linux网络栈 来自Linux内核文档.之前看过这篇文章,一直好奇,问什么一条网络流会固定在一个CPU上进行处理,本文档可以解决这个疑问.为了更好地理解本文章中的功能,将这篇文章穿插入内. 简介 ...
- Linux网络栈下两层实现
http://www.cnblogs.com/zmkeil/archive/2013/04/18/3029339.html 1.1简介 VLAN是网络栈的一个附加功能,且位于下两层.首先来学习Linu ...
- 理解 Linux 网络栈(1):Linux 网络协议栈简单总结 图
http://www.cnblogs.com/sammyliu/p/5225623.html
- Linux网络子系统
再Linux的世界里,万物皆文件,通过虚拟文件系统VFS,程序可以用标准的Linux系统调用对不同的文件系统,甚至不同介质上的文件系统进行读写操作.下面我们揭示Linux网络子系统的秘密 sockfs ...
随机推荐
- 学习日记9、easyui控件两次请求服务器端问题
<select id="BankCard" class="easyui-combobox" style="width: 600px;" ...
- field.getModifiers() 返回值
field.getModifiers() 返回值 public static final 的值是 25 private 的值是2 测试如下 Class clazz=MyModel.class; F ...
- bzoj 2002 Bounce 弹飞绵羊(分块)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 11202 Solved: 5698[Subm ...
- UVA 111 历史考试
题目描述:最长公共子序列的变形 题目序列中第i项是学生给第i号历史事件排出的序号,另外还给出了第i号历史事件的正确序号 求按照学生给出的序号排好历史事件后,所得的事件排序与历史事件实际发生的序列的最长 ...
- 1204C Anna, Svyatoslav and Maps
题目大意 给你一个有向图和一个路径 让你在给定路径中选出尽量少的点使得新路径的最短路长度和原路径相等 给定路径相邻两点间距离为1 分析 先floyd求出两点间最短路 之后每次对于点i找到所有跟它的最短 ...
- jdbc odbc JDBC-ODBC
https://zh.wikipedia.org/zh-cn/ODBC ODBC(Open Database Connectivity,开放数据库互连)提供了一种标准的API(应用程序编程接口)方法来 ...
- 双轴按键摇杆控制器控制TFTLCD(使用ADC1双通道DMA传输)
实验使用如下所示的双轴按键摇杆控制器,来控制TFTLCD上显示的直线.首先介绍一下双轴按键摇杆控制器.原理:十字摇杆为一个双向的10K电阻器,随着摇杆方向不同,抽头的阻值随着变化.本模块使用5V供电( ...
- day09—css布局解决方案之全屏布局
转行学开发,代码100天——2018-03-25 今天,本文记录全屏布局的的方法.全屏布局,即滚动条不是全局滚动条,而是出现在内容区域内,:浏览器变大时,撑满窗口. 如:设置下图中布局,其中top区, ...
- MySQL 安装示例数据库(employee、world、sakila、menagerie 等)
sakila 示例数据库官方资料及安装说明,注意查看示例数据库支持的版本是否匹配你的数据库. 为了测试,有时候需要大量的数据集,MySQL 官方提供了用于测试的示例数据库,下载页面在 这里. 下面以 ...
- linux使用pigz多线程压缩
因为tar zip是单线程的压缩,压缩起来很慢,这个使用使用pigz工具辅助就会使用多线程了. 安装 sudo apt install pigz 压缩 tar cvf - test.txt | pig ...