前言
你们好啊,我是汤小圆。面试
今天给你们推荐的是,TCP/IP协议的经典面试知识点总结,但愿对你们有帮助,谢谢。服务器
简介
咱们平时常常听到的TCP/IP
协议,实际上是一个协议族;网络
只不过由于TCP、IP是其中最核心的协议,因此平时统称为TCP/IP协议;并发
这个协议族里面还有其余协议,好比HTTP
、FTP
、SMTP
等;框架
TCP分层框架
下图是TCP/IP协议族的一个分层框架图,从上往下依次是应用层、传输层、网络层、链路层、物理层ide
假如我想在机器A上,发送一条"Hello World"到机器B,这个通信过程是个什么样子呢?测试
首先机器A的应用层将消息内容"Hello World"打包,而后经由传输层加上双方的端口号,网络层加上双方的IP地址,链路层加上双方的Mac地址,通过多个路由器和网关,最终到达机器B,而后机器B再反过来解析出消息内容"Hello World"url
简化以后的路径就是:消息实体+端口号+IP地址+Mac地址,封装发送,收到消息后,再反过来解包操做spa
下面咱们从上往下,依次介绍各个分层的做用.net
应用层
按照固定的协议格式打包、解包数据。
好比SMTP协议,虽然不一样公司的邮箱格式不尽相同,可是均可以解析对方发来的邮件内容,就是由于他们都遵循SMTP协议
传输层
决定数据要传输到远程机器的哪一个程序(端口),同时要代表数据来自源机器的哪一个程序(端口),实现端口之间的通信。
好比本地跑一个测试程序A,监听的是8080端口;远程跑的测试程序B,监听的是8080端口;
那么传输层就会把本机的8080端口和远程的8080端口都加到数据包上;
这样远程机器解析数据时,就知道要把数据传给哪一个程序。
网络层
指定双方的IP地址,并进行路由的寻址和转发
这里要明白一点就是,远程机器的IP地址不是一次跳转就能够到达的,要经过路由器和网关的屡次跳转,才会到达
这个能够参考视频《TCP/IP协议 - B站 - 马士兵》
链路层
指定远程机器的Mac地址(确保不会发错地方),以及本机的Mac地址
既然有了Mac地址来做为机器的惟一ID,为啥还要有网络层的IP地址呢?
缘由有两个
-
IP是会变化的,有可能今天你跟机器A在聊天,明天就变成机器B了,固然会乱掉了
-
如今的电脑太多了,数以千万计,从这么多电脑中找出某一个Mac地址,效率很低;可是IP不同,IP是由网段划分的,有点相似于邮编,这样就能够分段寻址,效率高不少
TCP的三次握手,四次挥手
三次握手
三次握手就是创建链接的过程,示意图以下所示
咱们来再把流程简化一点,就是:机器A发送链接请求到机器B -> 机器B收到后,确认并发送同步信号 -> 机器A收到确认信号后,再次发送确认信号到机器B
这里面涉及到几个关键词,下面列出一一说明下
标志关键词
-
SYN(Synchronize Sequence Numbers),同步信号,表示打算创建链接时的一个信号
-
ACK(Acknowledgement),数据确认信号,表示是否确认收到数据
状态关键词
-
LISTENING,监听状态,表示还没开始创建链接,正在监听等待链接的到来
-
SYN_SENT,SYN已发送,表示SYN已经发送,可是成功不成功还不知道
-
SYN_RCVD,SYN已收到,表示收到SYN信号,也已经给了应答,可是链接还没创建
-
ESTABLISHED,链接创建,表示双方已经创建了链接,能够开始相互通讯了
下面详细说下三次握手的链接过程
-
机器A发送同步信号SYN=1,请求创建链接,并附带序列号seq=x (机器A定义)
-
机器B收到链接请求(SYN=1),返回 同步信号SYN=1 和 数据确认信号ACK=1,并附带序列号 seq = y(机器B本身定义),确认序列号 ack = x + 1(方便机器A校验)
-
机器A收到机器B的反馈后,继续发送 确认信号 ACK=1,并附带序列号 seq = x + 1,确认序列号 ack = y + 1
为何要三次?两次行不行?
两次也能够,就是会出现脏链接和信息不对等问题。(开玩笑的,两次固然不行了,出现这么多问题,你们都不用通信了,天天光顾着创建链接了)
什么是信息不对等?它是怎么产生的呢?
信息不对等说的是,双方对于对方的信息处理能力了解的不一致
对于机器A来讲,它内部有四个跟报文收发能力有关的标志(我发送成功了吗,我接收成功了吗,对方发送成功了吗,对方接收成功了吗)
那么对于机器B来讲,也应有这四个标志
如今假设只有两次握手,那么当两次握手完成后,机器A的四个标志是都确认成功了,可是机器B内心却会有个两个疑问???
疑问1:我发送成功了吗?
疑问2:对方接收成功了吗?
这时就会产生信息的不对等。
就比如两我的用对讲机交流,我听到你的讲话了,我也回应了,可是你忽然不理我了。那我就对本身的表达能力产生疑问了。。。
下面这个表格很形象的说明了 两次握手致使信息不对等的问题
什么是脏链接?它又是怎么产生的呢?
了解脏读以前要先明白一个知识点,就是报文存活的时间 > 请求链接的超时时间(通常状况下)
如今假设咱们用的是两次握手,那么脏链接就是机器A有一次请求链接超时,而后请求重连,等到重连成功后,上一次超时的请求又来,此时这个请求对于机器B来讲就是脏链接
下面是产生两次握手产生脏链接的示意图
从图中能够看到,从新发送的链接请求,两次握手成功并断开链接后,以前超时的请求又来了,此时机器B发送第二次握手,链接创建;
可是由于此时客户端的状态是ESTABLISHED(已创建链接),而不是SYN_SENT(同步信号已发送),因此机器A不认这个链接,没法通信,也就成了脏链接。
四次挥手
四次挥手就是断开链接的过程,示意图以下所示
这里面涉及到几个上面没提到的关键词,下面列出一一说明下
标志关键词
-
FIN(Finish),完成信号,表示通信已经完成,接下来打算关闭链接了
状态关键词
-
FIN_WAIT_1,发送断开链接后的等待状态阶段1,表示已经发送了 FIN 请求,可是对方还没确认
-
FIN_WAIT_2,发送断开链接后的等待状态阶段2,表示对方 ACK 确认了,可是对方还没发送 FIN 请求
-
TIME_WAIT,固定时间等待期,表示对方已经发送了 FIN 请求 和 ACK 确认信号,我也发送了确认信号 ACK ,过一会就能够关闭链接了
-
CLOSE_WAIT,关闭等待期,表示接收到 FIN 请求,并发送了 ACK 确认信号,这边开始准备断开链接的收尾工做
-
LAST_ACK,最后确认,表示已经发送了 FIN 请求和 ACK 确认信号,等待对方 ACK 确认就能够关闭了
-
CLOSED,关闭状态,表示已经关闭链接
下面详细说下四次挥手的断开链接过程
-
机器A发送 FIN 信号,请求关闭链接,并附带序列号 seq = u
-
机器B收到 FIN 信号,返回 ACK 确认信号,并开始准备断开链接的收尾工做
-
等到收尾完成,机器B再发送 FIN 信号 和 ACK 确认信号,并附带序列号 seq = v, 确认序列号 ack = u + 1
-
机器A收到后,进入 TIME_WAIT 期,并发送 ACK 确认信号,附带序列号 seq = u + 1,确认序列号 ack = v + 1
-
机器B收到后,关闭链接
-
机器A等待固定时间(2MSL,下面会介绍这个参数)后,也关闭链接
为何握手是三次,挥手却要四次呢?
由于挥手多了一个清理现场的部分,就是发送剩余的数据,处理现场,关闭相关资源
其实若是没有什么能够清理的,机器B也可能省略这个阶段,而后在收到机器A的 FIN 信号时,直接返回 FIN 和 ACK 信号,这样就会变成三次挥手
2MSL是什么参数?
这个 2MSL 就是报文在网络上的生存时长,意思就是报文若是在网络上存在的时间超过这个参数,那么报文就会自动丢弃
这个数值若是过大,会形成资源的浪费
由于若是数值过大,好多链接就会卡在TIME_WAIT这里,还占着端口,那么这个端口就啥也不干了
因此通常建议这个数值调小一点(建议小于30S),尤为是在服务器端
那TIME_WAIT 这个阶段能够跳过吗?为何要在这里等待一段时间呢?
不能够,缘由有二
-
有可能机器A最后发完 ACK 确认信号后,对方没收到,此时机器A若是立马断开链接,就会致使报文丢失;
相反的,正由于有了这个阶段,因此当对方没收到ACK信号时,对方过段时间会重发FIN+ACK信号,此时机器A会从新发送ACK信号,并从新计时
-
防止失效请求,防止已失效链接的请求数据包和正常链接的请求数据包混淆而发生异常
已失效的链接,指的是握手过程当中因为某些缘由没有成功,可是也没断开的链接
如今有了这个TIME_WAIT阶段,那么前面已失效的链接就会由于超时而被丢弃,从而不会干扰到正常的链接
总结
以上只是关于TCP/IP协议的简单介绍,主要为了小白入门;
想深刻细节的能够参考《TCP/IP 核心技术卷一》和马士兵老师的B站视频
参考资料:
1. 《码出高效:Java开发手册》 2. 《TCP/IP 核心技术卷一》 3. B站马士兵视频:https://www.bilibili.com/video/BV1mA411q7Ry?p=7
图片来源:以上全部图片均来自《码出高效 Java开发手册》
后记
最后,感谢你们的观看,谢谢。