TCP三次握手与四次挥手

这里写图片描述

三次握手:

  • 第一次
    A发送连接请求报文段。首部中的同步位SYN=1,同时选择一个初始序号seq=x。此时A进入SYN_SENT状态。

  • 第二次
    B收到连接请求报文段后,如果同意建立连接,则向A发送确认。
    在确认报文段中把SYN和ACK都置1,确认号ack为x+1,同时自己也要喧杂一个初始序号seq = y。B进入到SYN_RCVD状态;

  • 第三次
    A收到B的SYN+ACK包,还要向B发出确认,ACK置1,确认号ack=y+1,自己的序号seq为x+1。
    此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

为什么要三次握手?
也就是为什么Client还要发出一次确认呢?主要是防止已失效的连接请求突然又传送到了Server。比如说Client发出了一个连接请求,但是这个请求报文在某些网络节点滞留了,这时Client会再发出一个连接请求,从而建立连接、数据传输然后释放连接。但是那个滞留的请求报文可能在某个时间到达了Server,Server误以为这时Client又发出一次新的连接请求,于是就向Client发出了确认报文,同意建立连接。
假设不采用三次握手,那么只要Server发出确认就会建立新的连接。但是由于Client此时并没有真的发出建立连接的请求,因此不会理睬Server的确认也不会向其发送数据,但Server却认为新的连接已经建立了并一直等待Client发来数据,此时Server的很多数据就这么浪费了。

采用三次握手的话可以防止上面现象的发生,例如在刚才的情况下Client不会向Server发出确认,Server由于收不到确认就知道Client没有要求建立连接,就不会傻傻等着了。


这里写图片描述
四次挥手:

  • A首先发出连接释放报文段,并停止发送数据,主动关闭TCP连接。
    A将FIN置1,其序号seq = u,等于前面已传送过的数据的最后一个字节的序号加1,此时A进入FIN_WAIT_1状态。

  • B收到连接释放报文后即发出确认,ACK置1,确认号ack=u+1,而这个报文段自己的序号是v,等于前面已传送过的数据的最后一个字节的序号加1。然后B进入到CLOSE_WAIT状态。

  • 这时从A到B这个方向的连接就释放了,TCP连接处于半关闭状态,即A已经没有数据要发送了,但若B还要发送数据,A仍要接收。

  • A在收到B的确认后,就进入到FIN_WAIT_2状态。

  • 若B已经没有要发送的数据了,就发送连接释放报文。FIN置1,序号seq为w,B还必须要重复上次已发送过的确认号ack=u+1。此时B进入LAST_ACK状态。

  • A收到B的连接释放报文后,要对此发出确认,ACK置1,确认号ack = w+1,自己的序号为seq = u+1。
    然后会进入TIME_WAIT状态。现在TCP连接还没有被释放掉,必须经过时间等待计时器设置的时间2MSL后A才进入CLOSED状态。MSL为最长报文段寿命,一般为2分钟。

为什么Client必须要等到2MSL时间呢?有两个原因:

  • 为了保证Client最后发出的ACK报文能够到达Server。
    这个ACK报文段可能丢失,此时Server收不到确认就会超时重传之前的FIN报文段,Client就可以在2MSL时间内收到这个重传的FIN报文,从而重传一次ACK确认,重新启动2MSL。
    如果Client不在TIME_WAIT状态等待一段时间而是在发送完ACK后立即关闭连接,那么就无法收到Server重传的FIN报文段,Server就不会按正常步骤进入CLOSED状态。

  • 防止“已失效的连接请求报文段”出现。
    和三次握手中防止的已失效的连接请求报文段的情况相同,Client在发送完最后一个ACK后,再经过2MSL时间,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值