首先要了解
TCP的标记
ACK就是确认报文,就是我反馈我收到这个报文了
**
ACK就是确认报文,就是我反馈我收到这个报文了,可以看到第一次握手不用确认,因为是第一个,而第二次三次,都要回复确认
第一次握手
发送端 同步SYN=1表示连接请求报文
序号seq=x 这个代表x以前的数据包都发过去了
第二次握手
接收端 回复SYN=1
ACK=1
seq=y代表接收段发送的是y以前的数据包,貌似与发送端的seq=x无联系
ack=x+1 代表我需要以x+1为序号的包了 ,下次发送端要给我发这个
第三次握手
发送端 ACK=1
seq=x+1 代表接收段发送的是x+1开头的数据包
ack=y+1 代表我需要第y+1开始的包了 ,下次接收端要给我发这个
seq 代表发送的包的序号
ack 代表想要的序号,下次对方要给我发的序号**
为什么要进行第三次握手?
答:为了防止无效的连接请求报文到达服务器而引起错误。
TCP发起建立连接的一方不会一直等待对方的回复,如果超时,他再次发起这个请求,上一个作废。
假设A给服务器发送了一个请求,但是由于网络原因迟迟没有到达B服务器。由于一直没收到服务器端的回复确认,所以就进行超时重传,上个就舍弃了,
然后新的请求很快的到达了B服务器,然后B服务器也很快的进行了响应,如果是两次握手的话,这样就建立了连接,但是上次因网络问题迟迟未到的第一个请求这时到达了B服务器,服务器依然会当成新的连接请求进行响应,(服务器只要响应,第二次握手就完成了)这时又会建立连接,这就会出现建立了两个连接的局面,然后这就会出现很多问题,例如服务器端认为完成了握手,可以发送数据了,于是一直处于等待数据状态,而发送端不理睬服务器端发来的请求(因为发送端的那个请求早就被清除了),不去发送数据,后果就是服务器一直等,这样就会浪费很多服务器资源
如果是三次握手的话,就会避免这个问题,因为比如第二次的新请求到达时,发送端就会又给服务器端发送个确认请求,表示接收到了,这样迟到的那个请求到达服务器端,然后返回到发送端时,发送端并不会响应。然后这个连接并不会建立,服务器也就不会白白等待。
四次挥手
四次挥手过程:
第一次挥手
1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
第二次挥手
2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
第三次挥手
4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
第四次挥手
5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
简答版:
第一次:先由客户端向服务器端发送一个FIN,请求关闭数据传输。开始停止发送数据。客户端进入FIN-WAIT-1(终止等待1)状态
第二次:当服务器接收到客户端的FIN时,向客户端发送一个ACK,其中ack的值等于FIN+SEQ,服务端就进入了CLOSE-WAIT(关闭等待)状态(但是这时只是说明客户端数据传输完成了,服务器端可能数据还没传输完成,此时客户端仍然能接受数据),客户端就进入FIN-WAIT-2(终止等待2)状态
(注意第二次的作用就是更早的回应客户端,然后先完成客户端的关闭请求,然后在进行等待服务端的请求,延长终止等待1而使得FIN和ACK一起发送即二三次挥手合并的构想是错误的)
第三次:服务器将最后的数据发送完毕后,然后服务器向客户端发送一个FIN,告诉客户端应用程序关闭。服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认
第四次:当客户端收到服务器端的连接释放报文后,必须发出确认,回复一个ACK给服务器端。其中ack的值等于FIN+SEQ,此时,客户端就进入了TIME-WAIT(时间等待)(即为2MSL)状态,服务器只要收到了客户端发出的确认,立即进入CLOSED状态
握手三次,为什么要4次挥手?
确保数据能够完整传输。
当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。
但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭SOCKET,它可能还需要发送一些数据给主动方后,(按照常理的话,第二次和第三次挥手应该一起回复FIN=1和ACK=1的,但是因为服务器端可能有数据没发完,所以不能也立刻去主动申请关闭,所以要把ACK和FIN分开)
再发送FIN报文给主动方,告诉主动方同意关闭连接,所以这里的ACK报文和FIN报文多数情况下都是分开发送的。
等待计时器
MSL就是最长报文寿命的意思
一般一个MSL设置2分钟 2MSL就是4分钟
一般一个TCP连接会占用一个端口,在等待计时器期间不会释放端口
作用:
1、确保第四次握手时发送方发送的ACK可以到达接收方
如果2MSL时间内没有收到,则接收方会进行重发
2、确保当前连接的所有报文都已经过期(每个具体TCP实现必须选择一个报文段最大生存时间MSL。它是任何报文段被丢弃前在网络内的最长时间。 2MSL足够使所有报文过期了)