tcp三次握手和四次挥手

来源:互联网 发布:手机怎样看网络直播 编辑:程序博客网 时间:2024/06/06 09:18

先来看一张整体的大图:
image

三次握手

先看一下三次握手的过程:
image

1. 第一次握手:首先由client端发出一个SYN报文,此时SYN=1,ACK=0,tcp协议中规定SYN报文不能携带数据,但是必须消耗一个序列号,这时候的请求如果在网络中失败了,会超时之后重传。此时client端进入一个SYNC-SEND状态,等待server确认;2. 第二次握手:server端收到SYN包之后,回复对方SYN ACK报文,设置SYN=1,ACK=1,seq=y(随机值),ack=x+1,这时候的请求如果在网络中失败了,会超时之后重传。此时server端进入SYNC_RCVD状态,client端仍在SYNC_SEND状态;3. 第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给ServerServer检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了

这里有一个问题需要阐述一下:为什么client在收到server的SYN ACK报文之后还需要回复一个ACK报文呢?
image

四次挥手

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。
看一下四次挥手的过程:
image

1. client首先发送FIN=1的报文,此时client端不会再向server发送数据,但是仍然可以接收server的数据,此时client进入FIN-WAIT-1的状态,此时如果网络有问题,client重传FIN包;2. server端收到FIN包后,回复一个ACK=1,seq=v,ack=u+1的报文,此时server端进入CLOSE-WAIT状态,此时server端仍然可以向client端发送数据;3. server端在数据发送完成之后,向client端发送FIN=1,ACK=1,seq=w,ack=u+1的报文,表示数据已经发送完成,server端不会再向client端发送数据,此时server进入LAST-ACK状态;4. client收到server报文后,回复server ACK=1,seq=u+1,ack=w+1的报文,确认连接可以断开,此时client端进入TIME-WAIT状态,server端在收到这个报文后就关闭这个连接,client在两个MSL时间之后,关闭连接;

这里面涉及到几个问题:

1. 连接中断可以是client也可以是server   假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了2. 在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。3. 为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?   理论上来说,四个报文发送完毕,就可以直接进入close状态了,但是必须考虑到网络是不可靠的,如果最后一个ack报文没有收到,那么server端会认为FIN ACK报文client报文没有收到,会重新发送FIN ACK报文,这时候如果client直接close了,将不会响应这个报文,服务端将会有很多连接处于close_wait状态。

在整个四次挥手过程中,client的状态变化如图:
image

server端状态变化:
image

0 0