曾今沧海难为水,除去巫山不是云。 ——《离思》·元稹
概述
我们通常所说TCP的三次握手、四次挥手实际上是指TCP的建立连接和释放连接。TCP是计算机网络中运输层的一种可靠传输协议,属于面向连接的,它传输的单位是报文段。
TCP建立连接(三次握手)
说明
1 TCP建立连接采用客户服务器模式,主动发起请求的是客户端,这里我们置为A,被动接受请求的是服务端,这里我们置为B。
2 连接的两端实质是两个进程,三次握手实际是传输了三次报文段,在连接的过程中两方确定好他们进行通信的一些参数,例如最大窗口值,时间戳选项服务质量等[1]。
3 最开始,服务器创建好传输控制块TCP,准备监听客户端进程的请求,自己进入监听(LISTEN)状态。若客户端需要与服务器建立连接,它也首先创建TCP,然后发送第一个报文段。
第一次握手
当确定A要和B建立连接时,A向B发送第一个报文段,把该报文段SYN标志位设为1,表示该报文段是一个连接请求报文段;把序号seq设为x,表示A发送的初始编号是x。该报文段是不携带数据的,但会消耗一个序号,此时A是SYN-SENT状态(同步已发送)
第二次握手
当B收到A发来的连接请求报文段后,若是同意连接请求,那么会发送连接接受报文段,该报文段首部中SYN=1,表示该报文段是连接接受报文段,ACK=1表示该确认报文段有效,ack=x+1表示B希望A发送的下一个序号,seq=y表示B发送的消耗序号,该报文段也是不携带数据的,只消耗掉一个序号。然后B进入SYN-REVD状态。
第三次握手
当A收到B发来的连接接受报文段后,需要再次向B发送确认报文段,此时并通知A的上层应用进程,TCP已经建立,可以开始传输数据了。而A发送的确认报文段首部中,seq=x+1表示A发送的字节流中第一个序号是x+1,并希望收到的下一个确认号是y+1,即把ack设为y+1。此报文段可以携带数据也可不携带数据,若不携带则不消耗序号,即可能下一个报文段序号仍可能是x+1,此时A进入ESTAB-LISTEN状态。
最后
当B收到A发来的确认报文段后,自己也进入ESTAB-LISTEN状态。A与B开始进行数据传输。
A再次发送确认报文段的目的(第三次握手目的)
为了防止已失效的连接请求报文段又发送一次给B,这种情况可能是由于A原来发送的连接请求报文段丢失或是其他异常情况。
TCP释放连接(四次挥手)
当数据传输结束后,A和B都可以释放连接,若A要释放连接,首先向TCP发送连接释放报文段,并停止发送数据,应用进程主动关闭TCP连接。
第一次挥手
A把连接释放报文段发送给B,并把报文段首部FIN=1,当前将不再发送数据,并要求B释放连接;同时发送自己的序号seq=u。
第二次挥手
B收到A发来的连接释放报文段后,将会通知上层应用进程,并发送确认报文段,设置报文段首部ACK=1,表示报文段确认号是有效的,设置确认号ack=u+1,还发送自己的序号v。此时A——>B这个方向的连接关闭,TCP处于半关闭状态,若是B还要发送数据给A,A还是得接着。
第三次挥手
若B不发送数据给A,那就通知进程关闭TCP连接,发送连接释放报文段给A,报文段首部FIN=1,表示不再发数据,连接释放,同时发送自己的序号w,确认号ack=u+1,并把ACK标志位置为1,表示该确认号是有效的。
第四次挥手
A收到B发来的连接释放报文段后,仍需发送确认报文段给B,表示他知道了。首部各字段就不再赘述。同时此刻A还需等待等待时间2MSL时间过后才真正释放掉。
2MSL它是时间等待计时器设置时间,MSL是最长报文段寿命。
设置等待时间为2MSL的原因:
1 为了保证A发送的最后一个ACK报文段能到达B。
2 为了防止上面提到的“已失效的连接请求报文段”出现在此连接中[1]。
TCP的有限状态机
说明
1 粗实线箭头表示客户进程的正常变迁
2 粗虚线箭头表示对服务器进程的正常变迁
3 细线箭头表示异常变迁
该图能很好的表现TCP连接各个状态的及其之间的关系
参考文献
[1] 谢希仁 计算机网络(第七版) [M] 北京:电子工业出版社 2017.1 ISBN 978-7-121-30295-4