敲黑板!!!
在软开岗的面试中,TCP的可靠性和TIME_WAIT状态是面试官进一步提问的不二选择!
小媛在面试中不止一次被问到,TCP的可靠性在一次笔试的简答题中也有出现过!
相关知识点
第一弹
a. TCP三次握手以及四次挥手过程描述;
b. 为什么要有三次握手和四次挥手;
第二弹
c. TIME_WAIT状态的描述以及作用;
d. TCP是通过哪些方式提供可靠性的?
第三弹
e. 拥塞控制与流量控制机制。
接上一篇
在第二弹中,我将介绍第三点和第四点的内容。
01 TIME_WAIT 状态
关于TIME_WAIT你应该知道
TIME_WAIT:表示收到对方的FIN报文并发送了ACK报文后,等2MSL后即可回到CLOSED状态了。如果FIN_WAIT_1状态下,收到对方同时带FIN标志和ACK标志的报文时,可以直接进入TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
首先要明确:执行主动关闭的那一端将会进入TIME_WAIT状态。该端停留在这一状态的持续时间为2MLS(MLS 最长生命分节期,是任何IP数据报在因特网中可以存留的最长时间)。
其次,我们要了解:分组在网络中“迷途”通常是路由异常的结果。某个路由器崩溃或者两个路由器之间的某个链接断开时,路由协议需要花费数秒到数分钟的时间才能稳定找出另一条通路。在这段时间内,可能发生路由循环(路由器A把分组发送给B,B又发送回给A),这种情况我们称之为迷途。
在迷途期间,发送端TCP超时并重传该分组,重传分组通过某路径到达目的地,而后不久(最多MSL秒)路由循环修复,早先迷失在这个循环中的分组最终也被送到目的地。这种分组被称之为重复分组或者漫游的重复分组,TCP必须要正确处理这些重复的分组。
TIME_WAIT状态为何存在
1. 可靠地实现了TCP全双工连接的终止
首先我们需要知道:当TCP向另一端发送数据时,他要求对端返回一个确认。如果在一定时间内没有收到确认,则会重发。
这里,对应于上图进行讲解。我们假设最终的ACK N+1 丢失,则服务器将会重新发送FIN N,因此客户端必须要维护状态信息,从而使它自己能够重新发送最终的那个ACK N+1。
如果没有了这个状态,当客户端第二次收到FIN时,会响应一RST(也是一种类型的TCP分节),会被服务器解释成一个错误。如果TCP打算执行所有必要的工作以彻底终止某个连接两个方向上的数据流(即全双工关闭),那么它必须要正确处理连接终止序列的4个分节中任何一个分节丢失的情况。
2. 允许老的重复分节在网络中的消逝
我们假设ip1:port1和ip2:port2 之间有一个TCP连接。我们关闭了这个链接,过一段时间后在相同IP和端口之间建立了另一个连接。TCP必须防止来自之前那个连接的老的重复分组在新连接上出现,出现误解的情况。
为了做到这一点,TCP将不复用处于TIME_WAIT状态的连接。2MSL的时间足以让某个方向上的分组存活MSL秒后被丢弃,另一个方向上的应答也最多存活MSL秒后被丢弃。
通过实施这个规则,就能保证,每成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已经在网络中消失了。
02 TCP如何保证可靠性
首先要讲一下,TCP也不能被描述成是100%可靠的协议,他提供的是数据的可靠递送或故障的可靠通知。
• 数据的合理分片与排序
TCP会按最大传输单元(MTU)合理分片。由 TCP传递给IP的信息单位称为报文段或段(segment)。既然TCP报文段作为 IP数据报来传输,而 IP数据报的到达可能会失序,因此 TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。
• 超时及重传机制
当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
TCP含有用于动态估算客户和服务器之间往返时间的(RTT)算法,以便它知道等待一个确认需要多长时间。(一般来说,RTT在一个局域网上大概需要几毫秒,跨越一个广域网大约需要数秒钟。另外,RTT还会会受到网络流通等各种因素的影响,TCP会持续估算一个给定连接的RTT)
• 数据校验
TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段(希望发端超时并重发)。
• 由于IP数据报会发生重复,TCP的接收端必须丢弃重复的数据。
• 提供流量控制机制
TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。
• 提供拥塞控制机制
当网络拥塞时,通过拥塞窗口,减少数据的发送,防止包丢失。
• 经受时延的确认(Delay ACK)
当TCP收到发自TCP连接另一端的数据,它将发送一个确认响应。这个确认不是立即发送,通常将推迟几分之一秒,以便将ACK与需要沿该方向发送的数据一起发送(有时称这种现象为数据捎带ACK)。绝大多数实现采用的时延为 200ms也就是说,TCP将以最大200ms的时延等待是否有数据一起发送,从而减少拥塞的可能性。
单个字节发送的缺点是什么?
每次只发送一个字节的数据,那么在网络中很有可能充斥着许多41字节长的分组(20的IP包首部,20的TCP包首部,1字节的数据),过多的这种小分组则会增加拥塞的可能性。
(这里的话,我在查资料的过程中,发现有些博客里认为:之所以推迟,可能是要对包做完整校验)欢迎后台留言讨论哦!
本文参考书籍主要为:《TCP/IP 详解 卷一:协议》、《UNIX网络编程卷1:套接字联网API》
有需要电子书的同学可以后台回复 “TCP” ,电子书仅作学习之用,禁止商用哦!
最后,小媛想说,如果您有哪方面的内容想要了解,可以在后台回复哦,我们会第一时间帮您解答哦!
作者:西瓜媛
编辑:西瓜媛
本文来自程序媛驿站,未经授权不得转载.