TCP 握手与挥手

来源:互联网 发布:hadoop能用python吗 编辑:程序博客网 时间:2024/05/23 12:47

注:以下内容部分来自谢希仁老师的《计算机网络》 第六版

一,TCP
TCP是面向连接的协议,运输连接是用来传送TCP报文的,它的运输连接的建立与释放是每一次面向连接的通信中必不可少的过程。因此运输连接就有三个阶段,即:连接建立,数据传送和连接释放。

二,TCP的连接建立(三次握手)

TCP首部(图片来自网络):
这里写图片描述

假设有主机a与主机b,其中a运行TCP客户程序,而b运行TCP服务器程序。最初两端的TCP进程都处于closed状态,建立连接的过程如下:

1,b首先创建TCP传输控制块,准备接收客户机的连接请求,服务器进程便处于LISTEN(监听)状态,等待客户的连接。

2,a也创建TCP传输控制块,然后向b发出连接请求报文段,这时首部中的同步位SYN=1,同时选择一个初始序号seq = x,TCP规定,SYN报文段(SYN=1)不携带数据,但要消耗一个序号。此时TCP客户进程进入SYN-SENT(同步已发送)状态。

3,b收到连接请求后,若同意连接,便向a发出确认,它在自己的报文段中将SYN与ACK位都置1,确认号ack=x+1,同时也为自己选择一个初始序号seq = y,该报文段也不携带数据,此时TCP服务器进程进入SYN-RCVD(同步收到)状态

4,a收到b的确认后,还要向b发出确认,确认报文段的的ACK置1,确认号ack = y + 1 ,而自己的序号
seq = x+1 。TCP标准规定,ACK报文段可以携带数据,但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是 seq=x+1 。此时TCP连接已经建立,a进入ESTABLISHED(已建立连接)状态。

5,当b收到a的确认后,也进入ESTABLISHED状态。

三,TCP的连接释放(四次挥手)
当数据传输结束后,通信的双方便可以释放连接。

1,假定a的应用进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。a把连接释放报文段首部的终止控制位FIN置于1,其序号seq = u ,它等于前面已传输过的数据的最后一个字节的序号加1。此时a进入FIN-WAIT-1(终止等待1)状态,等待b的确认(TCP规定,FIN报文段即使不携带数据,它也消耗一个序号)

2,b收到连接释放报文段后即发出确认,确认号为:ack =u + 1,而这个报文段自己的序号为v,等于B已传输过的数据的最后一个的序号加1, 然后b进入CLOSED-WAIT(关闭等待)状态。TCP服务器进程此时通知高层应用进程,因此从a到b这个方向的连接就被释放了,这时TCP连接处于半关闭(half-close)状态,即a已经没有数据要发送了,但b若还要发送数据,a仍要接受,意思是:从b->a这个方向的连接并未关闭,该状态可能会持续一段时间。

3,a收到b的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待b发出的连接释放报文段。

4,若b没有要再发的数据,其应用进程便通知TCP释放连接。这时b发出的连接释放报文段必须使FIN=1。现假定b的序号为w(在半关闭状态b可能又要发送一些数据)。b还必须重复上次已经发送过的确认号ack=u+1。这时b就进入了LAST-ACK(最后确认状态),等待a的确认。

5,a在收到b的连接释放报文段后,必须对此发出确认。在确认报文段中将ACK置1,确认号ack = w+ 1,
而自己的序号是seq=u+1,然后进入到TIME-WAIT状态。(时间等待)

6,此时,TCP连接并没有释放掉,必须要经过时间等待计时器设置的时间2MSL后,a才进入CLOSED状态。MSL叫做最长报文段寿命,RFC793建议设为2分钟。

三,为什么是三次握手,和四次挥手呢?

三次握手
假定网络中出现一种异常情况,当a第一次发出的连接请求报文段由于网络网络堵塞而滞留,若一段时间后,b又收到了该滞留的请求(本应该无效),但确以为a需要创建连接,便向a发出确认报文,若不采用三次握手,那么此时便已经建立连接了。在该种情况下由于采用三次握手,则a收到确认报文后便选择不予理睬,b由于收不到回复,便自然明白a没有要创立连接。

四次挥手
为什么是四次挥手呢?由于建立连接的是双方,所以当甲发出断开连接的请求后,乙便需要发出答复,收到确认信息后,甲便断开单向连接,等待乙发送数据,直到甲收到乙要断开连接的回复,需要向乙发出确认,此时才全部断开,所以需要四次。

四,为什么要TIME_WAIT

1,为了保证a发送的最后一个确认被b收到,在等待的2MSL时间内,若b没有收到回复,便会超时重传它的确认报文,此时a便可以收到,重发确认,然后重置等待时间。

2,防止已失效的报文段再次出现在本次连接中,当a等过2MS时间后,可以使本连接持续时间内所有产生的报文段都从网络中消失。