在介绍TCP链接的创建与释放以前,先回顾一下相关知识。 前端
TCP是面向链接的运输层协议,它提供可靠交付的、全双工的、面向字节流的点对点服务。HTTP协议即是基于TCP协议实现的。(虽然做为应用层协议,HTTP协议并无明确要求必须使用TCP协议做为运输层协议,可是由于HTTP协议对可靠性的的要求,默认HTTP是基于TCP协议的。如果使用UDP这种不可靠的、尽最大努力交付的运输层协议来实现HTTP的话,那么TCP协议的流量控制、可靠性保障机制等等功能就必须所有放到应用层来实现)而相比网络层更进一步,运输层着眼于应用进程间的通讯,而不是网络层的主机间的通信。咱们常见的端口、套接字等概念就是由此而生。(端口表明主机上的一个应用进程、而套接字则是ip地址与端口号的合体,能够在网络范围内惟一肯定一个应用进程) TCP协议的可靠传输是经过滑动窗口的方法实现的;拥塞控制则有着慢开始和拥塞避免、快重传和快恢复、RED随机早期检测几种办法。(这几个知识点在这里就先不细致总结了,你们能够回顾计网课本23333)面试
另外,TCP协议的报文格式也须要回顾一下: 缓存
TCP报文段的首部分为固定部分和选项部分,固定部分长20byte,而选项部分长度可变。(若整个首部长度不是4byte的整数倍的话,则须要用填充位来填充)在固定首部中,与本文密切相关的是如下几项:服务器
seq(序号):TCP链接字节流中每个字节都会有一个编号,而本字段的值指的是本报文段所发送数据部分第一个字节的序号。
网络
ack(确认号):表示指望收到的下一个报文段数据部分的第一个字节的编号,编号为ack-1及之前的字节已经收到。spa
SYN:当本字段为1时,表示这是一个链接请求或者链接接受报文。计算机网络
ACK:仅当本字段为1时,确认号才有效。设计
FIN:用来释放一个链接。当本字段为1时,表示此报文段的发送端数据已发送完毕,要求释放运输链接。
进程
下面就是本文的重点了:TCP的运输链接管理。 ip
运输链接具备三个阶段:链接创建、数据传送以及链接释放。运输链接管理就是对链接创建以及链接释放过程的管控,使得其能正常运行,达到这些目的:使通讯双方可以确知对方的存在、能够容许通讯双方协商一些参数(最大报文段长度、最大窗口大小等等)、可以对运输实体资源进行分配(缓存大小等)。TCP链接的创建采用客户-服务器模式:主动发起链接创建的应用进程叫作客户,被动等待链接创建的应用进程叫作服务器。
链接创建阶段:
第一次握手:客户端的应用进程主动打开,并向客户端发出请求报文段。其首部中:SYN=1,seq=x。
第二次握手:服务器应用进程被动打开。若赞成客户端的请求,则发回确认报文,其首部中:SYN=1,ACK=1,ack=x+1,seq=y。
第三次握手:客户端收到确认报文以后,通知上层应用进程链接已创建,并向服务器发出确认报文,其首部:ACK=1,ack=y+1。当服务器收到客户端的确认报文以后,也通知其上层应用进程链接已创建。
在这个过程当中,通讯双方的状态以下图,其中CLOSED:关闭状态、LISTEN:收听状态、SYN-SENT:同步已发送、SYN-RCVD:同步收到、ESTAB-LISHED:链接已创建
至此,TCP链接就创建了,客户端和服务器能够愉快地玩耍了。只要通讯双方没有一方发出链接释放的请求,链接就将一直保持。
链接释放阶段:
第一次挥手:数据传输结束之后,客户端的应用进程发出链接释放报文段,并中止发送数据,其首部:FIN=1,seq=u。
第二次挥手:服务器端收到链接释放报文段以后,发出确认报文,其首部:ack=u+1,seq=v。此时本次链接就进入了半关闭状态,客户端再也不向服务器发送数据。而服务器端仍会继续发送。
第三次挥手:若服务器已经没有要向客户端发送的数据,其应用进程就通知服务器释放TCP链接。这个阶段服务器所发出的最后一个报文的首部应为:FIN=1,ACK=1,seq=w,ack=u+1。
第四次挥手:客户端收到链接释放报文段以后,必须发出确认:ACK=1,seq=u+1,ack=w+1。 再通过2MSL(最长报文端寿命)后,本次TCP链接真正结束,通讯双方完成了他们的告别。
在这个过程当中,通讯双方的状态以下图,其中:ESTAB-LISHED:链接创建状态、FIN-WAIT-1:终止等待1状态、FIN-WAIT-2:终止等待2状态、CLOSE-WAIT:关闭等待状态、LAST-ACK:最后确认状态、TIME-WAIT:时间等待状态、CLOSED:关闭状态
统一解释几个问题:
一、在握手与挥手的过程当中,往复的ack与seq有什么含义?
这是通讯双方在通讯过程当中的一种确认手段,确保通讯双方通讯的正确性。例如小时候模仿电视剧里无线电呼叫的过程:“土豆土豆,我是地瓜,你能听到吗?”“地瓜地瓜,我是土豆,我能听到”。 若客户端的报文请求号为“土豆”,则服务器端就将返回确认号“土豆+1”(标志土豆已收到),是一种通讯双方的确认手段。
二、在结束链接的过程当中,为何在收到服务器端的链接释放报文段以后,客户端还要继续等待2MSL以后才真正关闭TCP链接呢?
这里有两个缘由:第一个是:须要保证服务器端收到了客户端的最后一条确认报文。假如这条报文丢失,服务器没有接收到确认报文,就会对链接释放报文进行超时重传,而此时客户端链接已关闭,没法作出响应,就形成了服务器端不停重传链接释放报文,而没法正常进入关闭状态的情况。而等待2MSL,就能够保证服务器端收到了最终确认;若服务器端没有收到,那么在2MSL以内客户端必定会收到服务器端的重传报文,此时客户端就会重传确认报文,并重置计时器。
第二个是:存在一种“已失效的链接请求报文段”,须要避免这种报文端出如今本链接中,形成异常。
这种“已失效的链接请求报文段”是这么造成的:假如客户端发出了链接请求报文,然而服务器端没有收到,因而客户端进行超时重传,再一次发送了链接请求报文,并成功创建链接。然而,第一次发送的链接请求报文并无丢失,只是在某个网络结点中发生了长时间滞留,随后,这个最初发送的报文段到达服务器端,会使得服务器端误觉得客户端发出了新的请求,形成异常。
三、若通讯双方同时请求链接或同时请求释放链接,状况如何?
这种状况虽然发生的可能性极小,可是是确实存在的,TCP也特地设计了相关机制,使得在这种状况下双方仅创建一条链接。双方同时请求链接的状况下,双方同时发出请求链接报文,并进入SYN-SENT状态;当收到对方的请求链接报文后,会再次发送请求链接报文,确认号为对方的SYN+1,并进入SYN-RCVD状态;当收到对方第二次发出的携带确认号的请求报文以后,会进入ESTAB-LISHED状态。 双方同时请求释放链接也是一样的,双方同时发出链接释放报文,并进入FIN-WAIT-1状态;在收到对方的报文以后,发送确认报文,并进入CLOSING状态;在收到对方的确认报文后,进入TIME-WAIT状态,等待2MSL以后关闭链接。须要注意的是,这个时候虽然不用再次发送确认报文并确认对方收到,双方仍需等待2MSL以后再关闭链接,是为了防止“已失效的链接请求报文段”的影响。 过程图以下:
这既是计算机网络中的重要知识,也是前端技术笔试、面试中容易涉及的问题,特整理~