TCP三次握手与四次挥手
TCP连接
TCP是面向有连接的,全双工的通信协议,进行通信的时候,需要通信双方先进行连接,结束通信的时候需要通信双方都断开连接。TCP通过三次握手建立连接,通过四次挥手取消连接
TCP协议

上图就是TCP报文
- 32位序号:用
seq表示,表示当前TCP报文最大的序号是seq,包括seq - 32位确认号:是接收到的
TCP报文的seq+1,表示包括序号seq在内的之前的报文都已经接收到了 ACK:当ACK的值为1时,表示接收方成功接收发送方发送过来的报文SYN:表示当前的报文是一个用来建立TCP连接的报文FIN:表示当前报文是一个用来取消TCP报文的连接,当某一方发出了这个报文,说明发送方数据已经发送完毕,不会再主动发送报文了
三次握手

- 客户端发送报文
SYN=1,seq=x给服务器,报文中SYN=1说明这是一个建立TCP连接的报文,发送完这个报文以后,客户端处于SYN-Sent状态 - 服务器就收到了来自客户端的建立
TCP报文,就处于SYN-RCVD状态,然后向客户端回复报文SYN=1,ACK=1,seq=y,ack=x+1,其中SYN=1表示这是一个建立TCP连接的报文,ACK=1表示服务器成功收到客户端发送过来的报文,seq=y表示服务器发送给客户端的数据的最大序号是y,ack=x+1表示服务器成功接收来自客户端的包括序号x的所有报文,注意ACK和ack是两回事,他们对应TCP报文首部的两个部分。 - 客户端接收到来自服务器端的响应报文,客户端就处于已连接状态
Established状态。并且向服务器响应报文ACK=1,seq=z,ack=y+1,这个报文不包含SYN了,这是一个正常通信的TCP报文,此时服务器端的状态也处于了Established
四次挥手

客户端和服务器通过四次挥手断开连接,断开连接可以通过客户端或者服务器端发起,在这里我们假设通过客户端发起断开连接
- 客户端发送报文
FIN=1,seq=u给服务器端,因为报文中包含FIN=1,说明这是一个断开连接报文,发送了这个报文以后,表明客户端不会再主动发送数据给服务器端(用于响应的ACK报文不是发送的数据,是被动的数据),此时客户端处于FIN-Wait-1状态 - 服务器端接收到来自客户端的断开连接报文,就发送响应报文
ACK=1,seq=v,ack=u+1,并且此时服务器端处于Close-Wait状态 - 客户端接收到来自服务器端的响应报文以后,就处于
FIN-Wait-2状态 - 此时服务器端依然可以向客户端主动发送数据,直到服务器端发送报文
FIN=1,ACK=1,seq=w,ack=u+1,此时TCP报文中FIN=1表明这是一个断开连接报文,发送了这个报文以后,说明了服务器端不会再主动发送数据给客户端了,此时服务器端处于Last-ACK状态 - 客户端接收到来自服务器端的
FIN报文以后就返回响应报文ACK=1,seq=u,ack=w+1,然后客户端处于Time-Wait状态,等待2MSL时间以后变为Closed状态 - 服务器端接收到
FIN报文的响应报文以后,也直接变为Closed状态
等待2MSL时间的原因:MSL表示报文在网络中的最大的存活时间,这个时间是可以配置的,当客户端向服务器端返回最后的FIN的响应报文的时候,如果此时网络中出现问题导致服务器端没有收到这个响应报文,那么服务器端就会再次发送FIN报文,然后客户端如果再次接收到FIN报文,就会重启计时器。如果没有这个计时器,客户端在接收到FIN报文以后直接处于Closed状态,那么当出现上述问题时,服务器端的连接就会一直不能关闭,因为服务器端只能发送FIN报文,但是不能接收到FIN报文的ACK报文。设置这是计时器还有一个原因,当客户端和服务器的连接都关闭以后,如果网络中还有发送给刚才那个连接相同端口的数据,当上一个连接在刚关闭的时候就重启连接的情况下,当前连接就会接收到属于上一个连接的数据,而如果设置了这个计时器,那么网络中的属于原来那个连接的数据就会在这一段时间里面从网络中消失。
是三次握手而不是四次握手的原因是服务器端返回的第一个响应中既包含了SYN,也包含了ACK,所以在这一步二合一了。
浙公网安备 33010602011771号