如果你觉得可以,请多点赞,鼓励我写出更精彩的文章🙏。
如果你感觉有问题,也欢迎在评论区评论,三人行,必有我师焉
你是什么样的人,便会遇到什么样的人;你想遇到什么样的人,就得先让自己成为那样的人
成为会写诗的程序员
概要
前言
这是2021年第一篇文章,其实这篇文章是临时起意
。本来关于网络
的东西,没打算这么早就写。因为,近期无论是工作还是自己的学习任务,网络都没有想更多的深入。而平时碎片化学习中,或多或少是了解一下相关的知识点,但是不够深入和透彻。有点填鸭式的知识获取--知道是什么
,但是具体为什么是这样,就有点如鲠在喉
,两眼相看泪眼的赶脚。
其实这本没有错,毕竟有时候在工作中,不会让你每天讨论这个技术是什么,而是让你利用这个技术来解决指定的问题。你知道有某个知识点,也是在扩充自己的知识面宽度。是为了,在以后的某个技术生涯阶段,能够快速通过系统的学习,将这块薄弱的知识点,变的更牢靠和扎实。
最近在学习Linux
的相关知识点。通过咨询身边的运维朋友,是否有好的入门资料。(我一直秉承的一个学习原则---专业的知识就需要请教专业的人)。论牛逼朋友的重要性(手动狗头)他给我推荐了一个入门资料 鸟哥Linux私房菜 当开始阅读进行填鸭式
学习的时候,发现里面所讲的不管是针对计算机理论还是网络都很有深度。通过阅读相关章节,对自己现存知识,有了进一步的理解和深入。
而通过学习鸟哥的文章,也是没有打算进行该篇文章的书写。直到,下班在地铁上翻阅其他学习资料的时候。突然发现如下的东东。
这是针对前端的一个 进阶路径图谱。或者用官网的话来讲--这是成为一个合格的 与时共进前端所需要经历的学习成长路线Step by step guide to becoming a modern frontend developer
沿着路线图,依次前行,猛然发现,首当其冲
的就是 Internet
,正如图中所描述的,作为一个合格的现代化前端,我们需要熟悉并掌握很多知识点,而这些知识点的可扩展性都很强。既可以用一句话一笔带过,也可以单开章节去探讨。
通过,鄙人现有知识点的掌握情况来分析,我认为学习图谱中针对网络虽然林林总总列了很多知识点,但是最核心的还是网络如何建立连接。而在整个网络协议中,传输层(transport layer)的协议就是干这个事的。所以,该篇文章我们来简单认识一下该阶段发生了啥。
由于网络所涉及的东西可深可浅,而该篇文章,是建立在本人已掌握的知识点并查询其他相关资料来阐述的。如果有不正确的地方,欢迎评论区提出,并一起讨论。
三人行,必有我师焉!
其实,用很多口舌来讲解--为什么要写这篇文章,通过 进阶路径图谱来引出 今年学习的方向和目标。也就是说,在接下来一年内,我会按照图谱中的路线来学习,并且如果感觉有值得输出的东西,也会及时输出。其实,在没看到图谱之前,规划了一些最近的学习和工作实践,就完美的契合图谱中的点。我们按照流程图中的某些节点来显示,排名不分先后1: Modern CSS ===> Style Components
2: Web Components
3: Type Checkers ===> TypeScript(从OOP方向分析)
4: SSR ===> Next.js
5: React ===> Fiber架构
新的一年,让我们继续扬帆起航,追随心中所想。
天道酬勤
时间不早了,该干点正事了,咱们书归正转。 (林志玲语音包) 👈 点击触发(上次有个小伙伴想听林志玲的语音包,那就满足你)
OSI七层协议
如果想了解网络协议,OSI
是绕不开的一座大山。那我们就来看看他是何许人也。
OSI是 开放式系统互联通信 参考模型(Open System Interconnection Reference Model) 其实OSI是一个 标准 ,他规范了如果想实现网络间的通信是需要满足一定的规范。
上面的图,展示的是,从应用层到物理层(从高层到低层)的各个层级所承担的职责。
既然OSI是两个不同端
进行通信的模型,那势必就会涉及发送和接收。
小二,上图
我们可以看到,在夸端进行数据处理的时候,数据发起方
将Data
一层一层的进行装箱处理(这个概念只是借用了,JS在处理基本类型数据发生的动作---把基本数据类型转化为对应的引用数据类型的操作,例如'北宸南蓁'.trim()
就是装箱处理) 这个知识点是不是有点猝不及防啊。数据接收方将Data
一层一层的进行拆箱处理。
在Data Link 层处理数据,有点不同。因为 该层是介于软件和硬件之间。所以,就需要额外的操作。偏向软件的部分则是由逻辑链接层 (logical link control, LLC) 所控制,主要在多任务处理来自上层的封包数据 (packet) 并转成 MAC 的格式, 负责的工作包括讯息交换、流量控制、失误问题的处理等等
在偏硬件媒体部分,主要负责的是 MAC (Media Access Control) , MAC 是网络媒体所能处理的主要数据报裹,这也是最终被物理层编码成位串的数据
这段代码是直接CV鸟叔的教材。 具体什么是LLC,可通过这个自行查阅。我现在是没搞懂。
============这是一个华丽的分割线===================
其实OSI我们可以用一个句子来记:
将OSI从高层到底层的每层第一个单词抽离成另外一个词,并组成一个句子(具象化思维)
All People Seem To Need Data Processing
这就是我平时为了记住新的东西,而采用的常用方式:
- 情感化认知
- 具象化思维
传输层
通过上文我们得知,OSI给我们规划了不同端进行通信的蓝图,而在实际场景中,真正的起作用的是 --->TCP/IP 网络分层模型(四层协议)
。
我们来看一下,他们直接的关系。
小二,上图
从图中,无论是OSI
还是TCP/IP
模型中Transport Layer
都是 C 位,而它所承载的事情,也是至关重要的。
传输层的职责:保证数据在 IP地址地址标记的两点之间 指定端口 有效的通信。而在该层是通过TCP/UDP协议进行对应通信。
- TCP ===> 有状态的协议,需要先与对方建立连接然后才能发送数据,而且保证数据不丢失不重复。===>TCP 的数据是连续的“字节流”,有先后顺序
- UDP ===> 无状态,不用事先建立连接就可以任意发送数据,但不保证数据一定会发到对方。 ===> UDP 则是分散的小数据包,是顺序发,乱序收
有状态的TCP协议
我们为了行文的方便,采用网络中最常用的一种交互场景 浏览器和服务器的数据交互。 浏览器为client
(发送端),服务器为server
(接收端)。(当然client和server也可以为同一个机器,也就是说该机器既充当客户端,也充当服务器)
我们通过分析OSI可知,要想将Data从client
安全的送达server
,需要将源data在浏览器中经过层层包装-----将源data封装到带有特定Header的包裹中。
而每层的数据包装都会按照该层级的作用来进行添加个性化的Header。
我们采用IPv4 (Internet Protocol version 4, 因特网协定第四版)来存储数据 ---> IPv4 记录的地址由于仅有 32
位。
我们先来简单介绍一下,Header中重要字段的含义(一些配置字段就省略了)。
- Source Port(源端口号) / Destination Port (目标端口号): 源端口号和目的端口号;用于区别主机中的不同进程,而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一的确定一个TCP连接;
- Sequence Number(分包序号):由于 TCP 封包必须要带入 IP 封包当中,所以如果 TCP 数据太大时(大于 IP 封包的容许程度), 就得要进行分段。这个 Sequence Number 就是记录每个封包的序号,可以让
server
重新将 TCP 的数据组合起来。 --> 主要用来解决网络报乱序的问题 - Acknowledge Number(回应序号):为了确认
server
确实有收到我们client
端所送出的封包数据。 当client
端收到这个确认码时,就能够确定之前传递的封包已经被正确的收下了。 回应序号应当是上次已成功收到分包序号加1。--> 用来解决不丢包的问题 - Code(Control Flag, 控制标识码):这个字段共有 6 个 bits ,分别代表 6 个句柄,若为 1 则为启动。(只介绍重要的句柄)
- ACK(Acknowledge):若为 1 代表这个封包为响应封包, 则与上面提到的 Acknowledge Number 有关。
- SYN(Synchronous):若为 1,表示
client
希望双方建立同步处理, 也就是要求建立联机。 - FIN(Finish):若为 1 ,表示传送结束,所以通知对方数据传毕, 是否同意断线,只是发送者还在等待对方的响应而已。
三次握手--建立有效通信
其实图中已经将过程描述的很清楚了。我们来大致过一下,握手过程
- 1
client
主动发起联机操作 ====>第一次握手
- 1.1 小于 1024 以下的端口启动时, 启动者的身份必须要是
root
才行,所以启动一个不需要root
权限的端口号 --->初始化Source Port
- 1.2
client
主动构建一个包,并且由于是主动发起
的,需要将控制标识码置为1 ,分包序列 seq设置为一个整数 X
- 2
server
响应联机操作 ====>第二次握手
- 2.1
server
必须起动了一个和第一次握手阶段发送Hader中Destination Port
对应的程序 ---> 初始化Destination Port
- 2.2 server主动构建另外一个包
- 2.2.1 控制标识码 ACK = 1 -->响应第一次握手的消息,并将回应序号置为 ack = X + 1
- 2.2.2 控制标识码 SYN = 1 --> 主动发起,并且将分包序列 seq = Y
- 3
client
回送确认分包 ====>第三次握手
- 3.1 client 接受到包,并且其中 ack = X(
clien
t 自己发送给server
的连接凭证) + 1 , 表明,server
同意client
发起的连接,并且自己发送给server
信物也是正确的 - 3.2
client
又重新构建一个包,并且将server
送给自己的信物 Y,加工之后,又再次送给server
- 3.2.1 控制标识码 ACK = 1 --> 响应第二次握手消息,并将回应序号重置为 ack = Y + 1
从上述的操作流程中我们看到:不论是服务器端还是客户端,都必须要透过一次 SYN 与 ACK 来建立联机
网络是双向的
为什么要三次握手
三次握手 的目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误
“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点 长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。
假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。
四次挥手--断开连接
天下没有不散的宴席,当两个端口通过TCP建立了有效的连接,但是没有对应数据的交互,该通道就一直被占用,那无疑就是在浪费资源。所以,需要一种机制来将连接进行断开。
话不多说,上图
主要流程我们就不再详细描述了。来简单讲述一下,关键点哇。
- 1 相比三次握手,四次挥手,在client 发起的时候,是将控制标志码由
SYN
换成FIN
, 而通过我们讲述 Header 字段的时候,就着重描述了他们各自的含义和用处。 - 2 可以看到,在第二次挥手和第三次挥手中间,有很多 未发送完成的数据,其实也好理解,在
server
接收到client
传入的 FIN 包时候,此时可能正处于某些 大包数据的发送阶段,如果此时直接回复 client 的断开操作。并且,如果 server FIN 包早于其他正常数据包到达 client。那这些本应该被 client 收录的数据,就会平白无故的丢失。
为什么要四次挥手
下面的文案,是我抄的。别问为什么,问就是,人家总结的比我好。
TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。
TCP是全双工模式,这就意味着,
- 当主机1发出FIN报文段时,只是表示
主机1
已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据; - 当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;
- 当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
最后,说一下,该篇文章的主体基调哇。注意,自认为这不是一篇,详细介绍网络通信的文章,而是从TCP/IP协议中,挑选了我认为比较重要的一层来描述。可能有些地方描述的不是很详细。但是,我感觉,配合我画的相关的示图,就会能大体清楚 三次握手/四次挥手的数据是如何流向的。
下一篇,如果还写网络方向的,会从IP层协议入手。因为我认为IP也是很重要的。(手动狗头)
欲知后事如何,请听下回分解
(单田芳语音包)👈 点击发音