建立连接
开始时
B先创建传输控制块并进入LISTEN状态等待A发送请求
A创建传输控制块后,在需要时可以向B发出连接建立请求报文段(设置SYN = 1并选择一个初始序号seq = x)此时A进入到SYN-SEND(同步已发送状态)
B在收到此报文后回复一个同步确认报文(SYN = 1,ACK = 1,选择一个初始序号seq = y,ack = x+1)
此时B进入SYN-RCVD(同步收到状态)
A在收到B给出的同步确认报文后需要给B一个确认(ACK = 1,seq = x+1,ack = y+1)
此时A进入到ESTABLISHED(连接已建立状态)
B在收到最后的确认报文后也进入到ESTABLISHED状态
此时TCP连接已经建立
A向B发送数据时第一个序号还是为x+1,因为ACK报文如果不携带数据不占序号
(为什么必须是三次握手)
【原因在于若有一个连接建立请求报文由于在某结点滞留时间过长(该报文段已经失效)以至于本次连接结束后B才收到这个已经失效的连接请求报文段,B会向A发送一个同步确认报文,但如果是两次握手,A不给出确认,此时B会认为连接已经建立而等待A发送数据,但A并没有发送建立请求因而对B不予理睬,从而浪费B的很多资源】
连接释放
A想要关闭连接发出一个连接释放报文(FIN = 1,seq = u,u为A向B发送的数据的最后一个字节的序号加1)
此时A进入FIN-WAIT-1(终止等待1状态)
B在收到连接释放报文后给A发送一个确认报文(ACK = 1,seq = v,ack = u+1)
此时B进入CLOSE-WAIT(关闭等待)状态
A在收到B发送的确认报文后进入FIN-WAIT2(终止等待2状态)
此时TCP连接中A对B的连接已经关闭,但B对A的连接并未关闭,B仍可以向A发送数据
当B对A发送的数据也发送完毕时,B向A发送一个连接释放报文(FIN = 1,ACK = 1,seq = w,ack = u+1)
此时B进入LAST-WAIT(最后确认)状态
A在收到B发送的连接释放报文后给B发送一个确认报文(ACK = 1,seq = u+1,ack = w+1)
此时A进入TIME-WAIT(时间等待)状态,需要等待2MSL(MSL最长报文寿命)后才会关闭
B在收到A发出的最后的确认报文后直接进入已关闭状态
(为什么要等待2MSL才能关闭)
【第一、B可能没收到A向B发送的最后的确认报文,在2MSL时间内,B可以重新向A发出连接释放请求
第二、本次连接中可能存在已失效的报文段,在2MSL时间内,这些报文段会从网络中消失】
(为什么是四次挥手,不是三次)
【因为A向B要发送的数据已经发送完毕可以关闭,但B还有要向A发送的数据没有发送完毕,只有当B的数据也发送完毕后才能发送连接释放报文,不可以确认报文和连接释放报文一起发送】
TCP的有限状态机
粗实线箭头表示对客户进程的正常变迁,粗虚线箭头表示对服务器进程 的正常变迁,细实线箭头表示异常变迁
连接建立和释放过程中若出现客户端和服务器端同时发送SYN报文,或FIN报文(CLOSING状态),则会出现图中异常变迁情况