0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

简述Linux系统收发网络数据包的过程

dyquk4xk2p3d 来源:码农猿星球 2023-05-05 10:04 次阅读

Linux 服务器收到网络数据包,需要经过哪些处理,一步步将数据传给应用进程的呢?应用进程发送数据包时,Linux 又是如何操作将数据包发送出去的呢?今天我们就来聊聊这个话题

在准备好接收网络数据包之前,Linux需要做很多准备工作,例如:网络子系统的初始化、协议栈的注册、网卡驱动的初始化、启动网卡等等,只有这些都准备好了之后,才能真正开始接收网络包。

网络协议栈

在介绍Linux收发网络数据包之前,我们先来了解一下Linux网络协议栈。

国际标准化组织制定了开放式系统互联通信参考模型(Open System Interconnection Reference Model),也就是 OSI 网络模型,该模型主要有 7 层,分别是应用层、表示层、会话层、传输层、网络层、数据链路层以及物理层。

由于 OSI 模型太复杂,提出的只是存在于概念和理论上的一种模型,分层太多,增加了网络工作的复杂性,所以没有大规模应用。 我们比较常见是TCP/IP 网络模型,Linux 系统正是按照这套网络模型来实现网络协议栈的。

TCP/IP 网络模型共有 4 层,分别是应用层、传输层、网络层和网络接口层,每一层负责的职能如下:

1、应用层 对应于OSI参考模型的高层,为用户提供所需要的各种服务,例如:FTP、Telnet、DNS、SMTP等.

2、传输层 对应于OSI参考模型的传输层,为应用层实体提供端到端的通信功能,保证了数据包的顺序传送及数据的完整性。该层定义了两个主要的协议:传输控制协议(TCP)和用户数据报协议(UDP).

3、网络层 对应于OSI参考模型的网络层,主要解决主机到主机的通信问题。它所包含的协议设计数据包在整个网络上的逻辑传输。注重重新赋予主机一个IP地址来完成对主机的寻址,它还负责数据包在多种网络中的路由。该层有三个主要协议:网际协议(IP)、互联网组管理协议(IGMP)和互联网控制报文协议(ICMP)。

4、网络接口层 与OSI参考模型中的物理层和数据链路层相对应。它负责监视数据在主机和网络之间的交换。事实上,TCP/IP本身并未定义该层的协议,而由参与互连的各网络使用自己的物理层和数据链路层协议,然后与TCP/IP的网络接入层进行连接。地址解析协议(ARP)工作在此层,即OSI参考模型的数据链路层。

87070764-ea68-11ed-90ce-dac502259ad0.png

接收网络数据包

8717db8e-ea68-11ed-90ce-dac502259ad0.png

网络数据包到达网卡后,按照FIFO顺序被存入网卡的接收队列,网卡通过 DMA 技术,将网络包写入到指定的内存地址(Ring Buffer)。

Ring Buffer是在网卡驱动程序启动时创建和初始化的,存储的是sk_buff缓冲区的描述符(物理地址和大小等)。

当网络包到达时,从Ring Buffer获取指向的sk_buff描述符,通过DMA将数据写入该地址。等sk_buff中的数据交由上层协议栈处理后,Ring Buffer中的描述更新为新分配的sk_buff。

接着网卡向 CPU 发起硬件中断,当 CPU 收到硬件中断请求后,根据中断注册表,找到注册的中断处理函数。

硬件中断处理函数会做如下的事情:

1、屏蔽网卡的中断

目的是避免CPU被频繁中断而无法处理其他任务,屏蔽中断是告诉网卡已经知道内存中有数据了,下次再收到数据包直接写内存就可以了,不要再通知 CPU 了。

2、发起软中断,恢复刚才屏蔽的中断

内核中的 ksoftirqd 线程收到软中断后,就会调用相应软中断的处理函数来轮询处理数据,即:从Ring Buffer 中获取一个数据帧,用 sk_buff 表示,作为一个网络包交给网络协议栈从下到上进行逐层处理。

网络协议栈对网络包的处理流程如下:

1、网络接口层

首先,网络接口层检查报文的合法性和正确性,如果不合法或报文校验不正确则丢弃,否则找出上层协议的类型(IPv4还是IPv6),去掉帧头、帧尾,然后交给上层即网络层处理。

2、网络层

网络层取出IP头,判断网络包下一步的走向,是转发还是交给上层。当确认网络包是要发送给本机后,就取出上层协议的类型(比如TCP或UDP),去掉IP头,然后交给传输层处理。

3、传输层

传输层取出 TCP 头或者 UDP 头后,根据四元组【 源 IP、源端口、目的 IP、目的端口 】,找出对应的 Socket,并把数据拷贝到 Socket 的接收缓冲区。

4、应用层

最后,应用层程序调用 Socket 接口,将内核的 Socket 接收缓冲区的数据拷贝到应用层的缓冲区。

到这里,一个网络包的接收过程就结束了。

发送网络数据包

我们了解了网络包的接收流程后,就很容易理解网络包的发送流程了。网络包的发送方向,正好跟接收方向相反。

首先,应用程序调用 Socket 发送网络包的接口。这是一个系统调用,会从用户态陷入到内核态的套接字层中。

套接字层会申请一个内核态的 sk_buff 内存,将用户待发送的数据拷贝到 sk_buff 内存,并将其加入到Socket发送缓冲区等待网络协议栈的处理。

由于网络数据包从应用程序传到内核时是原始数据,协议栈要在原始数据中加入通信约定才能保证数据到达服务端能被正确识别。网络协议栈从 Socket 发送缓冲区中,取出数据包,然后按照 TCP/IP 栈的分层(传输层、网络层、网络接口层),从上到下逐层进行处理,各层将协议的头信息不断插入到数据包中。

协议栈对发送数据包的处理流程如下:

1、传输层

在传输层,会为器添加TCP头,同时拷贝一个新的 sk_buff 副本,这是因为 sk_buff 在到达网卡发送完成的时候,会被释放掉,而TCP 协议是支持重传的,为确保网络包可靠传输,在收到对方的 ACK 之前,这个 sk_buff 不能被删除。

2、网络层

在网络层,主要会做这些工作:选取路由(确认下一跳的 IP)、填充 IP 头、netfilter 过滤、对超过 MTU 大小的数据包进行分片。处理完这些工作后会交给网络接口层处理。

3、网络接口层

网络接口层会进行物理地址寻址,以找到下一跳的 MAC 地址,填充帧头和帧尾,将其放到发送队列中。然后触发软中断告诉网卡驱动程序:队列中有新的网络包需要发送。驱动程序收到通知会通过 DMA ,从发送包队列中读出网络帧,并通过DMA将数据写入网卡的FIFO发送队列。

4、网卡设备

网卡设备从FIFO发送队列中取出数据包,将其发送到网络;当发送完成的时候,网卡设备会触发一个硬中断来释放内存,主要是释放 sk_buff内存和清理 RingBuffer 内存。最后,当收到这个 TCP 报文的 ACK 应答时,传输层就会释放原始的 sk_buff。

至此,一个网络包的发送流程就结束了。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    10990

    浏览量

    206734
  • Linux系统
    +关注

    关注

    4

    文章

    567

    浏览量

    26911
  • TCP
    TCP
    +关注

    关注

    8

    文章

    1271

    浏览量

    78290
  • 数据包
    +关注

    关注

    0

    文章

    229

    浏览量

    24094
  • 网络层
    +关注

    关注

    0

    文章

    39

    浏览量

    10253

原文标题:简述Linux系统收发网络数据包的过程

文章出处:【微信号:良许Linux,微信公众号:良许Linux】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Linux系统收发网络数据包的工作过程

    Linux 服务器收到网络数据包,需要经过哪些处理,一步步将数据传给应用进程的呢?应用进程发送数据包时,
    发表于 06-08 12:34 397次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>系统收发网络</b><b class='flag-5'>数据包</b>的工作<b class='flag-5'>过程</b>

    请问SRIO每次出传输数据包的个数,数据包负载大小怎么设置?

    本帖最后由 一只耳朵怪 于 2018-6-19 14:25 编辑 DSP一次发送16个数据包,每个数据包256字节,一次传输4096个字节。如果现在DSP向FPGA发送2048字节数据,后面2048个字节它自动为零,造成效
    发表于 06-19 05:22

    蓝牙mesh网络数据包的应用

    独特的概念,但其主要资产在于数据包,这也是它的一个差异化因素。它非常紧凑,这种紧凑性有助于确保蓝牙mesh网络的频谱效率和吞吐量。
    发表于 07-18 08:06

    如何检测数据包丢失?

    问题:我想做一个RFC2544速度测试。有人知道如何检测数据包丢失吗?数据中是否有UNIQ标识符(什么是RF2544数据包结构?)……我找不到这个信息。谢谢。
    发表于 03-13 08:56

    24L01收发数据包发送不成功

    原子哥我使用你的源程序做收发实验。我发现一次的数据包(数组)的长度不到33就发送不成功。这是什么原因啊
    发表于 04-13 00:10

    网络数据及摄像机丢的原因

      不少人在使用网络和监控摄像系统的时候都有遇到过数据的情况,数据的原因是多种多样的,以
    发表于 02-19 17:30

    如何使用优化的数据包软件降低网络功耗?

    如何使用优化的数据包软件降低网络功耗?
    发表于 05-25 06:45

    LS1046如何使用iperf3工具测试TCP数据包传输?

    LS1046: 我尝试使用iperf3工具测试TCP数据包传输。 找到一些速度为 10Mb/s 的重传。数据包大小为 60 字节。(网络链接为 100Mbps) ethtool notify
    发表于 05-10 08:07

    P4080 udp数据包接收乱序是什么原因造成的?

    我们有一个基于 P4080DS 的定制板。我们已经使用 QorIQ Linux SDK 构建了镜像。在我们使用 iperf 测试以太网功能的过程中,我们观察到一些数据包被乱序接收。无序数据包
    发表于 06-06 08:31

    modbus在通信的过程中如何实现大数据包的传输?

    modbus在通信的过程中如何实现大数据包的传输
    发表于 10-15 12:23

    你知道Linux网络数据包的接收过程

    网卡需要有驱动才能工作,驱动是加载到内核中的模块,负责衔接网卡和内核的网络模块,驱动在加载的时候将自己注册进网络模块,当相应的网卡收到数据包时,网络模块会调用相应的驱动程序处理
    发表于 04-22 17:29 448次阅读

    Linux网络包接收过程的监控与调优

    上一篇文章中《图解Linux网络包接收过程》,我们梳理了在Linux系统下一个数据包被接收的整个
    的头像 发表于 11-10 14:50 1465次阅读

    无线收发系统架构简述

    无线收发系统架构简述
    的头像 发表于 05-09 11:15 713次阅读
    无线<b class='flag-5'>收发</b><b class='flag-5'>系统</b>架构<b class='flag-5'>简述</b>

    Linux如何操作将数据包发送出去

    数据包之前,Linux需要做很多准备工作,例如:网络子系统的初始化、协议栈的注册、网卡驱动的初始化、启动网卡等等,只有这些都准备好了之后,才能真正开始接收网络包。
    的头像 发表于 06-17 16:00 716次阅读
    <b class='flag-5'>Linux</b>如何操作将<b class='flag-5'>数据包</b>发送出去

    Linux TCP底层的收发过程讲解

    我们继续探索高性能网络编程,但是我觉得在谈系统API之前可以先讲一些Linux底层的收发过程
    发表于 08-08 15:42 215次阅读
    <b class='flag-5'>Linux</b> TCP底层的<b class='flag-5'>收发过程</b>讲解