网络包如何在 Linux 中接收发送?后端面试必看

Linux 网络

网络是一种把不同计算机或网络设备连接到一起的技术,它本质上是一种进程间通信方式。

网络模型

为了解决网络互联中异构设备的兼容性问题,并解耦复杂的网络包处理流程,OSI 模型把网络互联的框架分为应用层、表示层、会话层、传输层、网络层、数据链路层以及物理层等七层,每个层负责不同的功能。

  • 应用层,负责为应用程序提供统一的接口。
  • 表示层,负责把数据转换成兼容接收系统的格式。
  • 会话层,负责维护计算机之间的通信连接。
  • 传输层,负责为数据加上传输表头,形成数据包。
  • 网络层,负责数据的路由和转发。
  • 数据链路层,负责 MAC 寻址、错误侦测和改错。
  • 物理层,负责在物理网络中传输数据帧。

七层过于复杂,所以实际使用的是更加实用的四层模型,即 TCP/IP 网络模型

TCP/IP 模型,把网络互联的框架分为应用层、传输层、网络层、网络接口层等四层,其中

  • 应用层,负责向用户提供一组应用程序,比如 HTTP、FTP、DNS 等。
  • 传输层,负责端到端的通信,比如 TCP、UDP 等。
  • 网络层,负责网络包的封装、寻址和路由,比如 IP、ICMP 等。
  • 网络接口层,负责网络包在物理网络中的传输,比如 MAC 寻址、错误侦测以及通过网卡传输网络帧等。
    下图帮助你更容易理解 OSI和 TCP/IP 模型的对比
    在这里插入图片描述

建议书籍:《TCP/IP 详解》的卷一和卷二

Linux 网络栈

有了 TCP/IP 模型后,在进行网络传输时,数据包就会按照协议栈,对上一层发来的数据进行逐层处理;然后封装上该层的协议头,再发送给下一层。
封装是在原始数据前后,增加固定格式的元数据。如下图

在这里插入图片描述

其中:

  • 传输层在应用程序数据前面增加了 TCP 头;
  • 网络层在 TCP 数据包前增加了 IP 头;
  • 而网络接口层,又在 IP 数据包前后分别增加了帧头和帧尾。

当数据封装完成后,整体网络包会变大,数据在物理链路(OSI 中的第 7层) 传输时,会按照网络接口配置的最大传输单元(MTU)进行传输。
一般默认值为1500(这也是 Linux 的默认值)。一旦网络包超过 MTU 的大小,就会在网络层分片,以保证分片后的 IP 包不大于 MTU 值。显然,MTU 越大,需要的分包也就越少,自然,网络吞吐能力就越好。

理解了 TCP/IP 网络模型和网络包的封装原理后,Linux 内核中的网络栈,其实也类似于 TCP/IP 的四层结构。

Linux 网络收发流程

下图Linux 网络栈结构图,结合实际看看 Linux 如何收发网络包

在这里插入图片描述

网络包的接收流程

数据通过网卡接收

网卡接收数据:当一个网络帧到达网卡后,网卡会通过 DMA 方式,把这个网络包放到收包队列中;然后通过硬中断,告诉中断处理程序已经收到了网络包。

网络帧分配缓冲区:接着,网卡中断处理程序会为网络帧分配内核数据结构(sk_buff),并将其拷贝到 sk_buff 缓冲区中;然后再通过软中断,通知内核收到了新的网络帧。

内核取缓冲区数据:接下来,内核协议栈从缓冲区中取出网络帧,并通过网络协议栈,从下到上逐层处理这个网络帧。

Linux 网络协议处理数据包

从下到上逐步处理网络帧这个过程如下(结合上图分析更容易理解)

  • 链路层检查报文的合法性,找出上层协议的类型(比如 IPv4 还是 IPv6),再去掉帧头、帧尾,然后交给网络层。
  • 网络层取出 IP 头,判断网络包下一步的走向,比如是交给上层处理还是转发。当网络层确认这个包是要发送到本机后,就会取出上层协议的类型(比如 TCP 还是 UDP),去掉 IP 头,再交给传输层处理。
  • 传输层取出 TCP 头或者 UDP 头后,根据 < 源 IP、源端口、目的 IP、目的端口 > 四元组作为标识,找出对应的 Socket,并把数据拷贝到 Socket 的接收缓存中。
    最后,应用程序就可以使用 Socket 接口,读取到新接收到的数据了。

为了更清晰表示这个流程,下面这个流程图左半部分表示接收流程,图中的粉色箭头则表示网络包的处理路径。
在这里插入图片描述

网络包的发送流程

了解网络包的接收流程后,就很容易理解网络包的发送流程,借助上图右边的流程。

  • 应用程序调用 Socket API(比如 sendmsg)发送网络包
  • 网络协议栈封装数据,按照 TCP/IP 栈逐步加元数据封装
  • 执行路由查找确认下一跳的 IP,并按照 MTU 大小进行分片
  • 分片后的网络包,再送到网络接口层,找到下一跳的 MAC 地址并封装。
  • 最后,通过软中断通知驱动程序,驱动程序通过 DMA 发送数据

文章总结

多台服务器通过网卡、交换机、路由器等网络设备连接到一起,构成了相互连接的网络。由于网络设备的异构性和网络协议的复杂性,国际标准化组织定义了一个七层的 OSI 网络模型,但是这个模型过于复杂,实际工作中的事实标准,是更为实用的 TCP/IP 模型。

TCP/IP 模型,把网络互联的框架,分为应用层、传输层、网络层、网络接口层等四层,这也是 Linux 网络栈最核心的构成部分。

  • 应用程序通过套接字接口发送数据包,先要在网络协议栈中从上到下进行逐层处理,最终再送到网卡发送出去。
  • 而接收时,同样先经过网络栈从下到上的逐层处理,最终才会送到应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值