具体如下图所示
上图描述了TCP连接从建立到断开的详细过程,以下就其中的具体报文细节展开讨论。
在TCP三次握手建立连接阶段,客户端首先向服务器发送一个SYN=1,Sequence=p的请求包。
如果服务器同意授予客户端该链接,则发送ACK=p+1,SYN=1,Sequence=q的回应包。
最后在客户端收到服务器的回应包以后,也会向服务器发送一个回应包,具体内容为ACK=q+1,SYN=0,Sequence=p+1。
对于TCP的断开则需要四次握手,为什么不是三次握手呢,具体原因为:
当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
断开连接的过程是由客户端首先发起的,首先,客户端会发送FIN=1,Sequence=m的断开连接请求包。
服务器端收到请求以后,会发送一个确认包ACK=m+1,Sequence=n。
此时,客户端到服务器端单方面的连接已经断开了,客户端不会再向服务器端发送数据包。而服务器还是可以向客户端发送数据的,如果服务器端发送s个数据包以后不需要向客户端发送数据了,此时可以向客户端发送断开连接请求。FIN=1,Sequence=m+s,ACK=m+1。
客户端收到服务器的断开请求以后,会发送一个确认包。Sequence=m+1,ACK=m+s+1;
注意,客户端发送最后一次ACK包以后,还会等待2MSL(最大报文段生存时间),因为在网络中包有可能会丢失,客户端等待2MSL的时间是担心服务器端没有收到ACK包,从而重发FIN请求。