首先,我们先说什么是”三次握手“和”四次挥手“
(1).先来介绍一下里面这些看起来比较高级的字母:
SYN--同步序列号请求
seq--全称”Sequence number“--序列号
ACK--确认
ESTABLISHED--链接正常建立之后进入数据传输阶段
SYN SENT--发送完第一个SYN报文,等待收到确认
SYN RCVD--收到第一次的传输请求,还未进行确认
(2).三次握手的步骤:
第一次:客户端发送初始序号x和syn=1请求标志
第二次:服务器发送请求标志syn,发送确认标志ACK,发送自己的序号seq=y,发送客户端的确认序号ack=x+1
第三次:客户端发送ACK确认号,发送自己的序号seq=x+1,发送对方的确认号ack=y+1
(1). 同上,我们先介绍这些字母:
FIN--请求断开连接
seq--全称”Sequence number“--序列号
ACK--确认
FIN WAIT 1--主动发送第一个FIN报文之后进入该状态
CLOSE WAIT--收到对方的关闭请求并进行确认进入该状态
FIN WAIT 2--已经收到第一个FIN的确认信号,等待对方发送关闭请求
LAST ACK--等待最后一次确认关闭的报文
TIME WAIT--收到对方的关闭请求并进行确认进入该状态
(2)四次挥手的操作方法:
1.三次握手的作用:能够让双方都能明确自己和对方的收、发能力是正常的。
2.(1).第一次握手时:客户端发送网络包,服务端收到了。
这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
(2).第二次握手时:服务端发包,客户端收到了。
这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。
从客户端的视角来看,我接到了服务端发送过来的响应数据包,说明服务端接收到了我在第一次握手时发送的网络包,并且成功发送了响应数据包,这就说明,服务端的接收、发送能力正常。
而另一方面,我收到了服务端的响应数据包,说明我第一次发送的网络包成功到达服务端,这样,我自己的发送和接收能力也是正常的。
(3).第三次握手时:客户端发包,服务端收到了。
这样服务端就能得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。
第一、二次握手后,服务端并不知道客户端的接收能力以及自己的发送能力是否正常。而在第三次握手时,服务端收到了客户端对第二次握手作的回应。从服务端的角度,我在第二次握手时的响应数据发送出去了,客户端接收到了。所以,我的发送能力是正常的。而客户端的接收能力也是正常的。
原因如下:
(1).两次达不到让双方都得出自己、对方的接收、发送能力都正常的结论。
(2).每次收到网络包的一方至少是可以得到的信息是:对方的发送、我方的接收是正常的。而每一步都是有关联的,下一次的“响应”是由于第一次的“请求”触发,因此每次握手其实是可以得到额外的结论的。而这种结论都是从自己发出的信息得到关于他人的信息。应该可以说成间接信息。
(3).我们从第三次握手可以不难看出,当第三次握手时,服务端收到数据包,表明看服务端只能得到客户端的发送能力、服务端的接收能力是正常的,但是结合第二次,说明服务端在第二次发送的响应包,客户端接收到了,并且作出了响应,从而得到额外的结论:客户端的接收、服务端的发送是正常的。
1.TCP连接是双向传输的对等的模式,就是说双方都可以同时向对方发送或接收数据。
2.每当关闭一次连接时,会发送指令告诉对方自己的状态,我要关闭连接了。这时对方会回一个ACK,此时一个方向的连接关闭。但是另一个方向仍然可以继续传输数据,等到发送完了所有的数据后,会发送一个FIN段来关闭此方向上的连接。接收方发送ACK确认关闭连接。
注意:接收到FIN报文的一方只能回复一个ACK, 它是无法马上返回对方一个FIN报文段的,因为结束数据传输的“指令”是上层应用层给出的,我只是一个“搬运工”,我无法了解“上层的意志”
。
在这里,可能比较不容易懂,那么先举个”渣男“分手的例子吧。我相信这样可能更直观一些。
1.小渣和小美热恋了几年后,他们之间的感觉越来越微妙,慢慢的小美发现小扎对自己的关心越来越少了。终于小渣抵不住异地恋的痛苦,移情别恋了,看上了新来的学妹,小渣决定分手了,给小美寄了封分手信。
分手就算了,居然还有脸要回送我的东西!渣男!小美,收到信后,气得跳脚,立马回了封信,让他滚蛋。
第二天,小美就去邮局,把渣男送给她的东西都打包寄还了给他。小美还不忘在信中提醒,收到东西之后给我回封信,不要到时候耍赖说没收到,我再也不想看见你了!渣男!
小渣收到小美寄的包裹之后,立马回了封信,说东西收到了,我们以后也别联系了
一段恋情就这么结束了。。
2.情侣之间分分合合,当然计算机之间的连接也经常需要断开连接,断开的方式竟然和情侣之间很相似。
1.客户端发送一个FIN包,表示要断开连接,并设置seq序列号为m到服务器端,客户端进入FIN_WAIT_1状态。
(小渣写分手信给小美,进入等待回信的状态)
2.服务器端收到客户端的FIN包后,就知道客户端想要断开连接了,于是返回一个ACK包,设置seq为m+1,服务器端进入CLOSE_WAIT状态。服务器端对客户端说,我知道你想要断开连接了,不过先等等,我这还有些数据没发完,你等我发完再关闭。
客户端收到服务器端的确认后,进入FIN_WAIT_2状态,客户端现在只接收服务器端的数据,不再发送数据。
(小美回信给小渣,同意分手,但是东西要整理下再寄给小渣,小渣进入等待包裹状态)
3.服务器端发送完所有数据之后,发送一个FIN报文,设置seq序列号为n,进入LAST_ACK状态,表示我的数据都已经发送完了,你可以断开连接了。
(小美给小渣寄回包裹,表示我们已经两清了,你收到之后给我回个信,就可以滚蛋了)
4.客户端收到服务器端的FIN包后,返回一个ACK包,设置seq序列号为n+1,客户端就进入了TIME-WAIT(时间等待)状态。服务器只要收到了客户端发出的确认,立即进入CLOSED状态,关闭的连接。
(小渣回信给小美说,你的包裹我收到了,我们以后不用再联系了)
6.注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,才进入CLOSED状态。
讲道理,四个报文都发送完毕,我们应该可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的。如果客户端发送出最后的ACK回复,服务器没有收到,服务器将不断重复发送FIN报文。所以客户端不能立即关闭,它必须确认服务器端接收到了该ACK。
“三次握手,四次挥手”看似简单,但是深究进去,还是可以延伸出很多知识点的。比如半连接队列、全连接队列等等。以前关于TCP建立连接、关闭连接的过程很容易就会忘记,可能是因为只是死记硬背了几个过程,没有深入研究背后的原理。