TCP之三次握手和四次挥手
TCP
定义(摘自维基百科):
传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。
通过以上的定义我们知道,TCP是网络七层模型中传输层的协议。
数据包结构
其中包含的内容很多(详细了解请参考维基百科-传输控制协议),这里只列出几个重要的点:
1.ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1。
2.SYN(SYNchronization) : 在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1. 因此, SYN置1就表示这是一个连接请求或连接接受报文。
3.FIN(finish)即完,终结的意思, 用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。
三次握手
所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。
三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的***和确认号并交换 TCP 窗口大小信息。
通俗理解:
实际上:
流程:
第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
完成了三次握手,客户端和服务器端就可以开始传送数据。
三次握手建立连接时,发送方再次发送确认的必要性?
主要是为了防止已失效的连接请求报文段突然又传到了Server,因而产生错误。假定出现一种异常情况,即Client发出的第一个连接请求报文段并没有丢失,而是在某些网络结 点长时间滞留了,一直延迟到连接释放以后的某个时间才到达Server,本来这是一个早已失效的报文段。但Server收到此失效的连接请求报文段后,就误认为是Client又发出一次 新的连接请求,于是就向Client发出确认报文段,同意建立连接。假定不采用三次握手,那么只要Server发出确认,新的连接就建立了,这样一直等待Client发来数据,Server的许多资源就这样白白浪费了。
四次挥手
当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的啊。那对于TCP的断开连接,这里就有了神秘的“四次挥手”。
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
什么是全双工:
全双工(full-duplex)的系统允许二台设备间同时进行双向数据传输。一般的电话、手机就是全双工的系统,因为在讲话时同时也可以听到对方的声音。
全双工的系统可以用一般的双向车道形容。两个方向的车辆因使用不同的车道,因此不会互相影响。
下面是四次挥手的流程图:
流程:
第一次分手:主机1(可以使客户端,也可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;
第二次分手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;
第三次分手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;
第四次分手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
四次挥手释放连接时,等待2MSL(即Maximum Segment Lifetime,也就是报文最大生存时间)的意义?
第 一,为了保证Client发送的最有一个ACK报文段能够到达Server。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的Server收不到对已发送的FIN和ACK 报文段的确认。Server会超时重传这个FIN和ACK报文段,而Server就能在2MSL时间内收到这个重传的ACK+FIN报文段。接着Server重传一次确认。
第二,就是防止上面提到的已失效的连接请求报文段出现在本连接中,Server在发送完最有一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。
TCP通信流程图