TCP三次握手四次挥手
三次握手
指的是在发送数据的准备阶段,服务器端和客户端之间需要进行三次交互:
OSI参考模型中的网络层,在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。(TCP在运输层,IP在网络层)
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的syn(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
通俗的说:
第一次握手:A(客户端):你好我是A,你听得到我在说话吗(发送建立连接请求,等待服务器确认) A->SYN_SEND
第二次握手:B(服务端):听到了,我是B,你听到我在说话吗(确认客户端的请求,同时自己也发送一个请求) B->SYN_RCVD | A->ESTABLISHED
第三次握手:A(客户端):嗯,听到了(确认服务端的请求,发送完毕,建立连接) B->ESTABLISHED
建立连接,开始聊天!
可能会有这种想法,为什么要进行三次握手才能建立连接,两次貌似也可以,事实三次握手是可靠的的连接过程:
三次握手的目的是 “为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误“
“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。
假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于是client发送的请求报文段滞留后才到达服务端,而现在client并没有发出新的建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。
采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。
四次挥手
当客户服务端传输完毕,需要终止连接的时候,就会进行四次挥手:
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
第一次挥手:TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
第二次挥手:服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
第三次挥手:服务器关闭客户端的连接,发送一个FIN给客户端。
第四次挥手:客户端发回ACK报文确认,并将确认序号设置为收到序号加1。
通俗的说:
第一次挥手:A(主机1):喂,我不说了,我听你说最后的话(只能接收)。 A->FIN_WAIT1
第二次挥手:B(主机2):我知道了。等下,我还没说完。Balabala….. B->CLOSE_WAIT | A->FIN_WAIT2
第三次挥手:B(主机2):好了,说完了,我也不说了。 B->LAST_ACK
第四次挥手:A(主机1):表示已收到。 A->TIME_WAIT | B->CLOSED
A等待2MSL,保证B收到了消息,否则A又要表达一次收到了 A->CLOSED