一、TCP协议简介
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,通过三次握手建立连接,通讯完成时要拆除连接。由于TCP是面向连接的,所以只能用于端到端的通讯。
二、TCP协议头部的格式:

三、TCP连接建立:
第一次握手:首先,客户端向服务端发送连接请求SYN报文。标志位SYN置为1,序号(随机)为j,即SYN=1 seq=j 。客户端进入SYN_SENT状态。
第二次握手:服务器接收到SYN报文后,发送SYN+ACK报文。将标志位的SYN和ACK都置为1,并将序号置为k,确认号置为j+1。即 SYN=1 ACK=1 seq=k ack=j+1 。服务器进入SYN_RECV状态。
第三次握手:客户端接收到SYN+ACK报文后,检查ACK与ack。检查无误,向服务器发送ACK报文,将标志位ACK置为1,确认号为k+1,即 ACK=1 ack=k+1。服务器接收到后,检查ACK与ack。检查无误,客户端和服务器进入ESTABLISHED状态,完成三次握手,建立TCP连接,开始传输数据。
简略版:
客户端:让我们建立连接吧!服务端!
服务端:好的客户端我收到了你发送的信息!让我们建立连接吧!
客户端:知道了服务端,我也能收到你发送的信息!
服务器得知客户端能接受到自己发送的信息,连接建立。
为什么要进行三次握手?
1.建立稳定的连接,双方都能向对方发送报文,也能确认对方能收自己的报文。
2.防止服务端因已失效的连接请求报文段浪费资源。
当客户端发出了一个连接请求报文,然而该请求却在网络中某节点被阻塞住了,以至于延误到连接释放以后的某个时间才到达服务端。此时服务器会向客户端发送确认报文,如果只有两次握手,那么此时连接就建立了…服务器将长时间等待客户端发数据,却一直等不到,造成资源的极大浪费。如果是三次握手呢,由于客户端并不会回复服务器的确认报文,连接并不会建立,节约了资源。
四、TCP连接中断
第一次挥手:客户端发起中断连接请求,发送FIN报文:将标志位FIN置为1,序号置为u。此时客户端进入FIN_WAIT_1状态,表示没有数据要传输给服务端了。
第二次挥手:服务端收到FIN报文后,发送ACK报文,表示同意关闭请求:标志位ACK置为1,确认序号为u+1。此时服务端进入CLOSE_WAIT状态,客户端接受到ACK报文后,进入FIN_WAIT_2状态。
第三次挥手:服务端再发送一个FIN报文,请求关闭连接:标志位FIN置为1,序号为w。服务端进入LAST_ACK状态,表示没有数据要传输给客户端了。
第四次挥手:客户端收到FIN报文后,发送一个ACK报文,确认序号为w+1,此时客户端进入TIME_WAIT状态。服务端收到ACK报文后,进入CLOSED状态。此时客户端会等待2MSL,如果没有收到回复,证明服务端已经关闭了连接,那么客户端也会关闭连接,进入CLOSED状态。至此,四次挥手完成,TCP连接断开。如果在TIME_WAIT状态中,客户端最后一次发送的ACK丢失了,它将重新发送。
简略版:
客户端:我要请求关闭连接!我没有数据要传输给你了!
服务端:好的我知道了!诶你等等,我看看还有没有数据没传输完!
服务端:关闭连接吧!客户端!
客户端:好的我知道了!
客户端等了2MLS后,并没有受到服务器的回复,得知服务端已经关闭了连接,于是自己也关闭了。
为什么要进行四次挥手?
因为TCP连接是全双工模式。当关闭连接时,一方收到另一方的FIN报文,仅仅表示另一方不再发送数据了,但是还可以接收数据,而自己也不一定将所有数据都发送给对方了。
表现就是,服务端接收到客户端发来的FIN报文时,不会立即发送FIN报文,而是会先回复一个ACK报文,并进入CLOSE_WAIT状态。这是因为服务端此时可能并没有传输完数据,只有当没有数据需要传输了,才会发送FIN报文给客户端,同意断开连接。而所以需要四次挥手。