上三篇文章分别提到了网络模型,http和https协议;
简单理解网络分层模型--向计算机网络迈一小jio
看懂Http协议,向计算机网络迈进一步~
站在HTTP“肩膀”上-看懂HTTPS协议
这三篇文章和这次要提到的TCP相关,不过之前的内容没有完全掌握并不影响理解TCP相关,但是还是强烈建议将前面的一点一点摸透,这样才能和TCP相关一起建立起来一个知识体系,不会那么容易忘记;
首先,为什么一定要将TCP相关啃下来?
原因1:理解TCP相关,尤其是三次握手和四次挥手过程,对于理解一个http请求从头到尾是如何建立起来的是非常重要的一环;
原因2:面试经常问啦!!!尤其是工作经历中写过和处理请求相关的,大概率会问的;
原因3:作为一个半路出家的“码农”,将这块啃下来,有利于以后理解更复杂的技术模型和流程;
开胃菜:开局一张图,让脑子有初步画面感;
在开始进入TCP话题之前,先看一张图,然后问自己几个问题(带着目的去学,印象更深刻)
A想和B交流,通过飞鸽传书的方式,必须有去有回,那么:
1.两个不同的端口开始传输数据之前,端口A如何确保端口B一定可以有能力接受到自己的数据?
2.端口A 收到了端口B有能力接收数据,但是端口A如何确保端口B知道自己(A)收到了端口B有能力接收的这件事情?
3.假如成功建立连接后,任意一方开始断开连接,如何确保正在传输的文件在断开连接之前传输完?
4.端口A开始断开连接之后,发出了断开连接的信号,但端口B一直没有收到断开信息,就可能一直保持打开状态等待,“占着茅坑不拉屎”,如何解决这样的问题?
好的,Study Time!!!
什么是TCP协议?
面向连接的,可靠的,基于字节流的传输层通讯协议,传输过程主要就是将报文段和资源段传给对方;TCP可以传很大的文件,但是并不是一次性整个传送过去,而是切分成一个个的分片,再把分片进行排序传送过去,并且数据传送到接受端并不是顺序的,而是需要重新排序,当然如何排序组装好完整文件接收端是知道的;
通俗讲:就是将需要传递的内容从整,从大拆分成一个个小段,逐个传输的一个从整到散再从散到整的传输层协议;画面感就像两家快递按照约定将大雕像分别拆分成“鼻子”,“耳朵”“头顶”等再标号1234依次传送,因为快递速度等原因不一定按照顺序运输到终点,但是陆陆续续拿到所有组件后,接收端根据编号可以完整的拼接出完整的雕像;(如自由女神像)
2.TCP协议的特点是什么?
*基于连接的
*全双工的
*字节流
*流量缓冲
*可靠的传输服务
*拥塞控制
(PS:这几个特点光看是看不懂且记不住的,需要结合下面的握手和挥手过程进行理解)
3.TCP连接相关的传递连接状态的TCP报文长啥样?
先来个英文的装个X;
再来个翻译版本压压惊;
不要一眼过,需要仔细梳理几个关键部分的作用;
*Sequence Number 序列号:用来保证数据的可靠性传输;开头提过的数据传输到接收端,到达顺序不一定有序,就可以根据序列号进行排序,假如排序过程发现丢包了就可以重传,或者因网络延迟导致重复发送,就会进行去重工作;
*Acknowledgement Number 确认号:用来保证数据的可靠性传输;
*Window 窗口:确认当前服务器可接受的大小,因为传输过程会根据对方给出的窗口值和当前网络拥堵程度决定一个报文段应该包含多少个字节大小;
*Urgent (Urgent Data pointer)紧急指针:紧急数据指针,如有这个的话,优先处理此报文数据;
*Options 选项:可选参数;
*Data 数据:分段传输的数据,可以理解为“主菜”;
*
确定此报文是什么,负责什么功能的报文,如:ACK 确认报文,FIN结束报文,SYN同步建立连接的报文;(这哥仨用的多)
重点补充:关于报文样式可以先略过,不影响理解三次握手四次挥手过程,但是在明白这过程之后,强烈建议回来返工,对照报文,一个一个的手绘一个自己看得明白的报文,也可以理解为照葫芦画瓢一点点做笔记。一定要亲自下笔手绘,你会发现一层新大陆;列一张我自己的笔记,很丑但是对加深我对tcp的理解有很大帮助;
4.TCP三次“握手”建立连接是怎么样的?
每一次握手都会对两端的状态有影响,所以先记住端口的几种状态:
*CLOSED 关闭状态;
*SYN-SENT 发送状态;
*LISTEN 监听状态;
*SYN-RECEIVED 接收状态;
*ESTABLISHED 确认开启状态;
TCP三次握手建立连接图解:(状态角度解析)
TCP三次握手 总体描述一下过程 就是,客户端和服务器端相互发送报文,确认彼此都有能力1.接收 2.发送数据--进而建立连接开始数据传输的过程;
首先,准备阶段:服务器端新建套接字,里面有自己的地址,并且开启Listen状态,准备随时接收客户端传递过来请求;
第一次握手 :客户端 将自己新建的存有自己地址的套接字,向服务端发送SYN请求报文以及生成的一个随机Sequence Number,初始化序列号X(实际不可能是X,只为了方便理解设为X),这是第一次握手表示自己可以发送数据;
第二次握手 :服务器端接收到SYN报文和其中的序列号X之后,就将X进行+1处理,生成随机序列号Sequence Number:Y,打包成ACK确认报文;然后发送给客户端,这是第二次握手:知道了客户端能发送消息了,然后通知客户端,服务端是可以接收和发送数据的;
第三次握手,客户端接收到 ACK确认报文,ACK-Number X+1,和Sequence Number:Y之后。知道了客户端可以接收和发送数据了,就将Sequence Number + 1处理=Y+1 打包成新ACK确认报文 再发送给服务器,通知对方我可以接收数据;
三次握手完成后 客户端和服务器端都开启,开始进行数据传输;
补充:如果没有基础的情况之下理解是很难的,需要反复思考琢磨,对照图片和过程详解,一步一步的分析;直到弄懂整个过程,想要最快速度理解整个过程,可以用最笨但是我觉得是最好的方法,就是自己手绘过程图;
仅供参考;
5.TCP四次“挥手”断开连接是怎么样的?
每一次挥手都会对两端的状态有影响,所以先记住端口的几种状态:
*CLOSED 关闭状态;
*CLOSED-WAIT 等待关闭状态;
*FIN-WAIT-1 一级等待状态;
*FIN-WAIT-2 二级等待状态;
*TIME-WAIT ;
*LAST-ACK ;
四次挥手 整体描述一下就是在保证 数据传输不受影响的情况之下,通知对方关闭之后自己也关闭的一个过程;(图是baidu找来的,我感觉画的挺好的)
第一次挥手:一般就是客户端 发送FIN结束报文和生成的SEQ-Number随机序列号U 给服务器端,通知服务器客户端要关闭了,然后自己进入一级等待状态;
报文图片在此,建议用另一个设备打开,并尝试随着每一次“挥手”过程,将SEQ-Number序列号,ACK-Numbr确认号,报文类别等标记出来,有助于理解四次挥手;
第二次挥手:服务器端接收到FIN结束报文 和序列号U之后,将序列号U+1 赋予 ACK-Number; 然后生成一个新的序列号SEQ-Number V , 打包成ACK确认报文给客户端,客户端收到ACK确认报文之后 进入二级等待状态,等着服务端(先把文件传输完,还有继续接收可能没有传输完的数据之后)发送FIN结束报文 ;
第三次挥手:相互之间传输的数据完成了之后,服务器端向客户端发送结束报文FIN ,包含SEQ-Number序列号W ,ACK-Number U+1确认序列号 (相当于回应),发送给客户端;
第四次挥手:客户端接收到 FIN报文 ,开始进入TimeWaiting的状态 ,并且返回ACK确认报文 还有ACK-Number W+1还有 SEQ-Number U+1给服务器,服务器接收到之后 Close;客户端等一段时间关闭;图片中的2MSL指的是等待大概两个来回的时间;
补充:重点先理解三次挥手建立连接的过程,当理解了“三次挥手”后,用同样的方法梳理“四次挥手”就会非常快了;
6.关于TCP常见的面试题有哪些?
前言:我个人习惯是这样的,我不喜欢直接死背题,而是先将某一个技术栈等从模块流程角色的角度慢慢剖析梳理并且手动画出流程图和逻辑图之后,再开始看常见的面试题有那些,根据自己的理解进行准备和解答,这样基本上印象很深刻,如果在可以搭配实际使用经验和经历的话就更好了,基本上很难忘记,就算忘了也可以很快回想起来;
6.1 在四次挥手中,为什么需要等一段时间客户端才能关闭?
主要是万一人家服务端没收到ACK 那些信息的话怎么整,等待一段时间的话,就给服务端一些时间 加入人家没收到 服务器就再发送一次刚才说过的那些信息,说白了就是 我发送了 结束报文了,但是我没有收到确认的信息,那我就再发一次,但是如果 没有等待时间直接关闭的话,就可能会产生一些比如说 服务端没有收到最后一次挥手需要的确认报文啥的 然后就一直等待,堆积一个两个三个。。。。越来越多 服务器就崩溃了;
因为服务端在接收到FIN结束报文之后
, 往往不会立即返回FIN结束报文
, 必须等到服务端所有的报文都发送完毕了,才能发FIN
。因此先发一个ACK确认报文,
表示已经收到客户端的FIN
,延迟一段时间才发FIN
。这就造成了四次挥手。
6.3 如果是三次挥手会有什么问题?
等于说服务端将ACK
和FIN
的发送合并为一次挥手,这个时候长时间的延迟可能会导致客户端误以为FIN
没有到达客户端,从而让客户端不断的重发FIN
。
6.4 还想继续看面试题的可以到这个链接,不过在我看来理解底层比背面试题更重要;
https://juejin.cn/post/6844904070889603085
7.小结;
学习这件事情,手千万不能懒!
我发现最笨的方法也是最有效的方法,我每次学一些知识,就会用笔和纸,手写笔记并且画图,哪怕是抄下来,我也要一点点带着脑子和思考抄完,虽然很费时间且有点烦,但是总比自己囫囵吞枣,眼睛会了但脑子不会强得多!
生活感慨:
最近看到很多博主在散播某某大厂裁员了,哪家公司又让员工毕业了,说实话,内心是有一点点焦虑的,不过相比裁员,慢慢夯实专业技能,累计专业知识,并且持续学习才是每个人手里的“王炸”;我在持续学习,努力早日实现财务自由,女朋友在努力学习,希望能成功上岸,过上自己想要的生活!就业形势的确不咋地,但好在我们还很年轻,还可以从头再来!一起加油吧!
另外住进新房子真的好开心啊,哈哈哈!虽然位置有点偏,但是每天起床都能在自己家看江的感觉实在是太爽了;
顺手给自己打个广告~每多一个粉丝,我持续学习并且总结的动力就会多一分~一起加油!