【读书笔记-《网络是怎样连接的》- 5】Chapter2_4-网卡的工作过程
IP模块组装好的数据包,就可以交给网卡进行发送了。本篇就来介绍网卡在发送数据包时的工作过程。
1 以太网基础
以太网是一种为多台计算机能够彼此自由和廉价地相互通信而设计的通信技术,原型如下图所示。这种网络的本质其实是一根网线,通过收发器这种设备将不同网线之间的信号连接起来。
在这样的网络结构中,一台计算机发送的网络包会到达网络上所有其他的计算机。为了判断网络包是发送给谁的,增加了MAC头部,使用其中的MAC地址来判断网络包发送的目的地。这就是最初的以太网。
后来经过改进,先是有了中继式集线器结构,然后又有了交换式集线器的结构,如下图所示。
二者的区别在于中继式集线器结构中,网络包仍然会到达网络中所有的设备,而交换式集线器结构中,网络包只会发送给MAC地址对应的接收方。(中继式集线器简称为集线器,交换式集线器简称为交换机)。经过改进之后,以太网的3个性质仍然保持不变:通过MAC头部中的接收方MAC地址将网络包发送到目的地,通过MAC头部中的发送方MAC地址来识别发送方,通过以太类型识别包的内容。可以认为具备这三个性质的网络就是以太网。
2 网卡工作原理
2.1 网卡构成与初始化
IP模块生成的网络包还只是一串0和1的数字信息,需要通过网卡将数字信号转换为电信号或者光信号才能在网线上进行传输。网卡的主要工作过程如图所示,只代表其基本构成要素,并不代表实际的硬件构成。
与其他硬件一样,在操作系统启动时,网卡需要先由网卡驱动程序进行初始化后才能进入可以使用的状态。初始化过程包括硬件错误检查、初始设置等步骤,这些与其他硬件设备相同。还有一些以太网设备特有的初始化操作,如控制MAC模块中设置MAC地址。前面已经讲过,网卡的ROM中保存着网卡的MAC地址,将其读出就可以对MAC模块进行设置了。此外还有通过命令行或者配置文件设置网卡MAC地址的方法。真正生效的是网卡驱动程序初始化时在MAC模块中设置的MAC地址,可能与ROM中的MAC地址并不一致。
完成初始化操作后,网卡就可以进行网络包的收发操作了。
2.2 网络包结构
网卡驱动从IP模块接收到网络包之后,将其复制到网卡缓冲区内,然后通知MAC模块进行发送。
MAC模块将数据从缓冲区中取出后,首先会在开头加上报头和起始帧分界符,在末尾加上用于检测错误的FCS(帧校验序列),如下图所示。
报头是一串0和1交替出现的序列,长度为56比特,用于确定包的读取时机。为了理解报头的作用,先要说明如何通过电信号来读取数据。
用电信号表达数字信息时,需要用电信号的值对应0和1;而通过电信号读取数字信息,则是要从电信号中解析出0和1。为了判断出每个比特的分界线,需要在数据信号之外再发送一组时钟信号。在时钟的上升沿(或下降沿)时从数据信号中读取,根据值对应0或1就可以了。
这样产生了新问题。长距离传输时,网线较长,两根线路的长度会发生差异,数据信号和时钟信号会产生时间差。为了解决这个问题,可以采用将数据信号和时钟信号叠加在一起的方式。采用这种传输方式,我们需要从信号中找出时钟周期,从而提取出信号中的数据。报头的作用就在于此。在发送数据包前先发送一段用于测量时钟信号的特殊信号。
起始帧分界符则是用来表示包起始位置的标记。FCS用来检查包传输过程中可能出现的错误。它是一串32比特的序列,与CRC校验码一样,如果原始数据发生了变化,则FCS的值就会不同,从而可以判断数据发送过程中是否出现了错误。
2.3 网络包的发送
加上报头、起始帧分界符和FCS之后,网络包就可以通过网线发送出去了。有两种方式:使用集线器的半双工模式与使用交换机的全双工模式。全双工模式会在第三章详细介绍,这里来介绍一下半双工模式。
半双工模式中需要避免信号碰撞,因此发送前需要先判断网线中是否有其他设备发送的信号。如果有,则等待该信号传输完毕后再发送。发送过程中,MAC模块将数字信息转换为电信号,再通过称为PHY或者MAU的信号收发模块发送出去。
PHY(MAU)还需要监控接受线路中是否有信号进来。在开始发送前需要先确认没有其他信号进来,才能开始发送。在信号开始发送到发送结束的这段时间内没有信号进来,发送操作就完成了。也有很小的可能会出现多个设备同时发送网络包的情况,这时候就会发生信号碰撞。此时设备会停止发送,还会发送一段时间的阻塞信号,通知其他设备。
等待一段时间后,设备会再次重新发送。但如果所有设备都等待同样的时间,仍然会发生碰撞。因此会根据MAC地址生成一个随机数,等待随机的时间。在网络拥塞的时候,发生碰撞的可能性会提高,这样每次发生碰撞之后,就将等待时间延长一倍,以此类推。多次尝试仍然不行,就上报错误信息。
2.4 接收返回包
接下来来看网络包接收时的操作方式。在半双工模式中,一台设备发送的信号会到达集线器上的所有设备,接收操作的第一步就是将所有信号都接收过来。
接下来的操作与发送步骤相反。先通过报头同步时钟,然后将起始帧分界符后面的信号转换为数字信息。PHY(MAU)模块先将信号转换为通用格式,发送给MAC模块,MAC模块再将信号转换为数字信息,存放在缓冲区中。在存入缓冲区之前,MAC模块会检查FCS,如果FCS有问题,则直接丢弃这个包。如果没有问题,则检查MAC头部中的MAC地址是否与网卡初始化时分配给自己的MAC地址一致,如果不同,也直接丢弃。如果MAC地址一致,才会存入缓冲区中,并通过中断通知操作系统收到网络包。中断程序会调用网卡驱动,从网卡的缓冲区中取出收到的包,并通过MAC头部中的以太类型字段判断协议的类型。根据前一篇的内容,返回0800表示TCP/IP协议栈,于是下面会交给IP模块进行处理。
IP模块先是检查IP头部,格式没有问题则会检查IP头部中的接收方IP。客户端计算机不会进行包转发操作,因此如果IP头部中的接收方IP与自己的IP不一致,一定是发生了错误,IP模块会通过ICMP消息将错误告知发送方。
如果IP正确,则这个包会被接收下来。IP模块还有一项工作,即将分片的包还原成原始的包。关于分片功能,会在第三章详细介绍。分片的包会在IP头部的标志字段中进行标记,同一个包的分片具有相同的ID。此外IP头部的分片偏移量字段则表示了此分片在整个包中所处的位置。根据这些信息,在所有分片收到之后,就可以还原成原始的包了。接下来交给TCP模块进行处理。
3 UDP协议收发操作
前面详细讲解了TCP协议,这里简单介绍一下UDP协议。
TCP设计的复杂,是为了将数据高效且可靠地发送给对方,确保只重发出错或者未收到的包。但在数据很短的情况下,其实不用TCP这样复杂的机制,也可以高效地重发数据。如果只有一个包,发生了错误只要直接重发就好了,不必建立连接与断开连接的控制包。而发送数据后,将对方的回复作为接收确认也就可以了,也不再需要专门的接收确认包了。
这种情况下适用的就是UDP协议。UDP没有TCP的接收确认,窗口等机制,在发送时只需要将数据加上UDP头部,然后交给IP模块发送就可以了。
另一个使用UDP的场景是发送音视频数据的时候。音视频数据需要在确定的时机到达,如果错过了时机,再重发也没有用了。音视频播放过程中出现一些包的丢失可能只是产生一些失真或卡顿,一般也是可以接受的。
到这里第二章协议栈与网卡的部分就整理完毕了。下一章将会继续介绍网络包如何经过集线器、交换机与路由器等设备到达互联网。
相关文章:

【读书笔记-《网络是怎样连接的》- 5】Chapter2_4-网卡的工作过程
IP模块组装好的数据包,就可以交给网卡进行发送了。本篇就来介绍网卡在发送数据包时的工作过程。 1 以太网基础 以太网是一种为多台计算机能够彼此自由和廉价地相互通信而设计的通信技术,原型如下图所示。这种网络的本质其实是一根网线,通过…...

qt QOperatingSystemVersion详解
QOperatingSystemVersion 是 Qt 提供的一个类,用于表示和管理操作系统的版本信息。它允许开发者获取操作系统的名称、版本号和平台信息。这个类对于需要根据操作系统版本执行特定操作的应用程序尤其有用。 1. 构造函数 QOperatingSystemVersion(): 默认构造函数&…...

openpnp - 解决“底部相机高级校正成功后, 开机归零时,吸嘴自动校验失败的问题“
文章目录 openpnp - 解决"底部相机高级校正成功后, 开机归零时,吸嘴自动校验失败的问题"概述笔记问题现象1问题现象2原因分析现在底部相机和吸嘴的位置偏差记录修正底部相机位置现在再看看NT1在底部相机中的位置开机归零,看看是否能通过所有校…...

Python字幕滚动:为视频添加专业级动态效果!
Python实现由下向上滚动字幕 在数字媒体和编程领域,动态文本效果总能吸引观众的注意力。其中,滚动字幕是一种常见的视觉效果,经常用于视频、演示文稿和网页中。在Python中,我们可以通过多种方式来实现滚动字幕效果,比…...

Linux 系统中,将网络配置从 DHCP 改为静态 IP的几种方法
Linux 系统中,将网络配置从 DHCP 改为静态 IP 可以通过几种不同的方法来实现,下面是几种常见的方式: 方法一:使用 connman(Connection Manager) 如果你已经在使用 connman 管理网络,可以通过修…...
【jellyfin】解决Edge 浏览器播放 jellyfin 的 hevc/h265 视频“该客户端与媒体不兼容,服务器未发送兼容的媒体格式”错误
文章目录 问题原因分析解决方法 问题 在 windows 系统自带的 Edge 浏览器里网页播放 jellyfin 媒体库里的 hevc/h265 编码的视频时,总是提示 该客户端与媒体不兼容,服务器未发送兼容的媒体格式,无法播放视频。 原因分析 Edge 浏览器默认不…...

企业管理系统设计思路——毕业论文设计
根据企业对人事管理的要求,本系统可以实现以下目标: l 操作简单方便、界面简洁美观。 l 在查看员工信息时,可以对当前员工的家庭情况、培训情况进行添加、修改、删除的操作。 l 方便快捷的全方位数据查询。 l 按照指定的条件对员工进行统…...
Android 默认去掉URL网络校验,设置不进行网络校验
Android 系统连接WIFI显示网络连接受限分析处理_安卓13类原生系统网络受限-CSDN博客 package\modules\NetworkStack\src\com\android\networkstack\util\NetworkStackUtils.java public static final String CAPTIVE_PORTAL_MODE "captive_portal_mode"; //0 不…...

Python | Leetcode Python题解之第515题在每个树行中找最大值
题目: 题解: class Solution:def largestValues(self, root: Optional[TreeNode]) -> List[int]:if root is None:return []ans []q [root]while q:maxVal -inftmp qq []for node in tmp:maxVal max(maxVal, node.val)if node.left:q.append(n…...
Java泛型:类型安全的艺术
Java泛型是JDK 5中引入的一项重要特性,它为Java带来了类型安全的机制,极大地提升了代码的可读性和可维护性。泛型允许程序员在编译时检测非法类型,从而避免了运行时的ClassCastException异常,使得代码更加健壮和可靠。 泛型的基本…...
Redis 淘汰策略 问题
前言 相关系列 《Redis & 目录》(持续更新)《Redis & 淘汰策略 & 源码》(学习过程/多有漏误/仅作参考/不再更新)《Redis & 淘汰策略 & 总结》(学习总结/最新最准/持续更新)《Redis &a…...

技术成神之路:设计模式(二十二)命令模式
相关文章:技术成神之路:二十三种设计模式(导航页) 介绍 命令模式(Command Pattern)是一种行为设计模式,允许将请求(命令)封装为对象,从而使您可以使用不同的请求、队列或记录请求日…...
facebook账号类型有哪些?
Facebook的主要账号类型 在Facebook上,用户可以基于不同的目的和需求创建不同类型的账号,主要包括以下几类: 1. 个人账号 这是最常见的Facebook账号类型,每个用户都可以创建一个个人账号,分享生活动态、与朋友互动、…...

Flutter鸿蒙next 中如何实现 WebView【跳、显、适、反】等一些基础问题
✅近期推荐:求职神器 https://bbs.csdn.net/topics/619384540 🔥欢迎大家订阅系列专栏:flutter_鸿蒙next 💬淼学派语录:只有不断的否认自己和肯定自己,才能走出弯曲不平的泥泞路,因为平坦的大路…...

机器视觉:9点标定的原理与实现
一、什么是标定 标定就是将机器视觉处理得到的像素坐标转换成实际项目中使用到的毫米坐标。简单说即使看看实际单位距离内有几个像素,如下图所示,10mm的距离内有222个像素,那像素坐标和实际的毫米坐标就有个比例关系了。 二、九点标定 9点标…...

《深度学习》 了解YOLO基本知识
目录 一、关于YOLO 1、什么是YOLO 2、经典的检测方法 1)one-stage单阶段检测 模型指标介绍: 2)two-stage多阶段检测 二、关于mAP指标 1、概念 2、IOU 3、关于召回率和准确率 4、示例 5、计算mAP 一、关于YOLO 1、什么是YOLO YOL…...
什么是Kubernetes?K8s基础与工作原理
什么是 Kubernetes(K8s)? Kubernetes,通常简称为 K8s,是一个用于自动化部署、扩展和管理容器化应用程序的开源容器编排平台。它由 Google 于 2014 年开源,后来交由 CNCF(Cloud Native Computin…...
HTML5新增属性
1、HTML5 1.1 新增布局标签 header:用于定义文档或者section的页眉;footer:用于定义页面或section的底部信息;nav:用于定位页面上的导航链接部分;article:用于定位文档或者页面中的独立部分&a…...
软件开发术语(E开头)---持续更新
e—business 电子商务EAI (enterprise application integration)企业应用程序集成(整合)EBCO (empty base class optimization) 空基类优化(机制)Edge and Vertex Connectivity 割边/割点 Edge Coloring 边染色 EDI (Dlectronic Data Interchange)电子数据交换effic…...

多机器人编队避障算法(1)
文章目录 前言一、基于感知的避障1.基于感知的Epuck2避障思路(理论)2.基于感知的Epuck2避障实现(现实)3.距离传感器结合红外传感器修复避障Bug4.问题5.代码逻辑图 二、基于人工势场力的避障1.基于人工势场的Epuck2避障思路(理论)2.基于人工势场力的Epuck2避障实现(现实) 三、两…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...