TCP 三次握手和四次挥手

在OSI七层模型中,每一层的作用和对应的协议如下:

这里写图片描述

传输控制协议TCP(Transmission Control Protocol)—— 提供 面向连接的、可靠的 数据传输服务。
TCP工作在OSI七层模型中的第四层——传输层,其数据传输的单位是 报文段(segment)。
IP在第三层——网络层,其数据传输的单位是 分组或包(packet)。
ARP在第二层——数据链路层,其数据传输的单位是 帧(Frame)。

TCP 三次握手

TCP是面向连接的,无论哪一方向另一方发送数据前都必须建立连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换TCP窗口大小信息。

这里写图片描述

第一次握手:发送连接请求。客户端发送连接请求报文段,将 SYN 位置置1,序列号(Sequence Number) 为 x;然后,客户端进入 SYN_SENT 状态,等待服务器确认。

第二次握手:服务器收到 SYN 报文段。服务器收到客户端发来的 SYN 报文段,需要对这个报文段进行确认,设置确认号(Acknowledgment Number)为 x + 1 (序列号 + 1);同时自己还要发送SYN 请求信息,将 SYN 位置置1,序列号为 y ;服务器将上述所有信息放到一个报文段( ACK + SYN )中,一并发给客户端,服务器进入 SYN_RCVD 状态。

第三次握手:客户端收到服务器的 SYN + ACK 报文段。然后将确认号设置为 y + 1,向服务器发送 ACK 报文段。这个报文段发送完毕后,客户端和服务器都进入 ESTABLISHED 状态,TCP 的三次握手完成。

完成三次握手,客户端和服务器就可以进行数据传输。

四次挥手

数据传输结束后,通信双方都可以释放连接。现在主机 1 和主机 2 都处于 ESTABLISHED 状态。

第一次挥手:主机 1 (可以是服务器,也可以是客户端)的应用进程向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。 主机1 把连接释放报文段首部的终止控制位 FIN 置 1,其序列号为 x + 2(等于前面已传送数据的最后一个字节的序号加 1)向主机 2 发送 FIN 报文段;此时主机 1 进入 FIN_WAIT _1状态,等待主机 2 的确认,这表示主机 1 没有数据要发送给主机 2 了。

第二次挥手:主机 2 收到连接释放报文段后即发出确认。 主机 2 收到了主机 1 发送的 FIN 报文段,向主机 1 回了一个 ACK 报文段,确认号为 x + 3 ( 序列号+1 ), 这个报文段的序号是 v,等于主机 2 前面已经传送过的数据的最后一个字节的序列号加 1。然后主机 2 就进入 CLOSE_ WAIT 状态。从主机 1 到主机 2 这个方向的连接就释放了,这时TCP处于半关闭状态,即主机1已经没有数据要发送了,但主机2若发送数据,主机1 仍要接收。

第三次挥手:主机 1 收到来自主机 2 的确认后,就进入 FIN_WAIT _2 状态,等待主机 2 发出的连接释放报文段。 若主机 2 已经没有要向主机 1 发送的数据,其应用进程就通知 TCP 释放连接。这时主机 2 发送的连接释放报文段必须使 FIN = 1。现假定序列号为 y + 1(在半关闭状态可能又发送了一些数据)。主机 2 还必须重复上次已经发送过的确认号 x + 3。这时主机 2 就进入 LAST _ACK 状态,等待主机 1 确认。

第四次挥手:主机 1 收到主机 2 的连接释放报文段后,必须对此发出确认。 主机 1 收到主机 2 发送的 FIN 报文段,向主机 2 回了一个 ACK 报文段,在确认报文段中把 ACK 置 1,确认号为 y + 2,然后进入 TIME_WAIT 状态;主机 2 收到主机 1 发送的报文后,就关闭连接;此时主机 1 等待 2MLS 后依然没有收到回复,则证明服务器已经关闭了连接,那么主机 1 也关闭连接。

至此,TCP 四次挥手完成。

为什么要 3 次握手?

为什么 TCP 建立连接需要三次握手,怎么感觉两次就够了?

在谢希仁的《计算机网络》中是这么解释的:为了防止已失效的连接请求报文段突然又到了服务端,因而产生错误。

“已失效的连接请求报文段”产生在这样一种情况下:

    Client 发出的第一个连接请求报文段并没有丢失,而是在某个网络节点长时间滞留了,以致延误到连接释放以后的某个时间才到达 Server。本来这是一个早已失效的报文段,但Server 收到此失效的连接请求报文段后,就误以为是 Client 再次发出的新的连接请求。于是就向 Client 发出确认报文段,同意建立连接。如果不采用“三次握手”,那么 Server 发出确认后连接就建立了。由于 Client 并没有发出连接请求,因此不会理睬 Server 的确认,也不会向 Server 发送数据。但 Server 却以为新的连接已经建立,一直等待 Client 发来数据。这样 Server 的很多资源就白白浪费掉了。采用“三次握手”可以防止上述现象的发生。当  Client 没有向 Server 的确认发出确认时,Server 由于受不到确认,就知道 Client 并没有要求建立连接。

防止了服务器一直等待而浪费资源。

挥手过程中为什么必须等待 2MSL 的时间呢?

注意:时间 MSL 叫做最长报文段寿命(Maximum Segment Lifetime).

在第四次挥手时,为什么主机 1 在 TIME_WAIT 状态必须等待 2MSL 的时间呢?这有两个理由。

第一,为了保证主机 1 发送的最后一个 ACK 报文段能够到达主机 2。这个 ACK 报文段有可能丢失,因而使处于 LAST_ACK 状态的主机 2 收不到对已发送的 FIN + ACK 报文段的确认。主机 2 会超时重传这个 FIN + ACK 报文段,而主机 1 就能在 2MSL 时间内收到这个重传的 FIN + ACK 报文段。接着主机 1 重传一次确认,重新启动 2MSL 计时器。最后,主机 1 和主机 2 都正常进入到 CLOSED 状态。如果主机 1 在 TIME _WAIT 状态不等待一段时间,而是在发送完 ACK 报文段后立即释放连接,那么就无法收到主机 2 重传的 FIN + ACK 报文段,因而也不会再发送一次确认报文段。这样,主机 2 就无法按照正常步骤进入 CLOSED 状态。

第二,防止“已失效的连接请求报文段”出现在本连接中。主机 1 在发送完最后一个 ACK 报文段后,再经过 2MSL ,就可以使本连接持续时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。

保活计时器(keepalive timer)

除时间等待计时器外,TCP 还设有一个保活计时器。设想有这样的情况:客户已主动与服务器建立了 TCP 连接。但后来客户端的主机突然出故障。显然,服务器以后就不能再收到客户发来的数据。因此,应当有措施使服务器不要再白白等下去。这就是使用保活计时器。服务器每收到一次客户的数据,就重新设置保活计时器,时间设置通常是两小时。若两小时没有收到客户端的数据,服务器就会发送一个探测报文段,以后则每隔 75 分钟发送一次。若一连发送 10 个探测报文段后仍无客户响应,服务器就认为客户端发生了故障,接着就关闭这个连接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值