TCP 连接的建立和终止

TCP连接的建立

    三次握手

image

  1. 服务器端准备好接收外来的链接,通过该socket、bind、listen3个函数完成,为被动打开
  2. 客户端通过connect函数主动建立连接,通过发送一个SYN(带序号)
  3. 服务器确认(ACK)客户的SYN,确认序号为服务SYN的序号加1,同时发送一个SYN(带序号)
  4. 客户端确认(ACK)服务的SYn,确认序号为服务SYN的序号加1.

   如上就是我们通常所说的三次握手

 

TCP连接的终止

     四次握手

  image

  1. Client调用close主动关闭(通常是Client,也可以是server)。发送一个FIN(带序号)。进入FI_WAIT1状态
  2. 接收到FIN的对端执行被动关闭。发送ACK确认。然后进入CLOSE_WAIT。对端接收到ACK进入FIN_WAIT_2。此时为单方向关闭。
  3. 对端调用close执关闭。发送FIN(带序号)。进入LAST_ACK状态。
  4. 接收到FIN的client发送ACK确认,进入TIME_WAIT状态。
  5. Server接收到ACK之后进入CLOSED状态。完成连接的关闭。

如上为连接关闭的四次握手。

CLOSE_WAIT

    Server接收到Client的FIN回复ACK之后进入CLOSE_WAIT状态。此时Client到Server的连接关闭。Client不能向Server发送数据。而此时Server仍可以向Client发送数据。

即此时为单向的连接关闭。需要Server也执行close关闭,才能转入之后的状态。

   有时我们发现server有大量的close_wait,原因就是对方关闭了连接,而这边由于忙于读写或其他原因,没有执行关闭。

TIME_WAIT

    Client端接收到Server的FIN发送相应的ACK之后,进入TIME_WAIT状态。该状态的持续时间最长为MSL(maximum segment lifetime)的两倍,即2MSL。

RFC1122的建议值为2分钟,而Berkeley的传统实现为30秒。所以其持续时间在1分钟到4分钟之间。

    其存在是为了保证最后的ACK可以成功达到。否则会在MSL之后,Server重新发送FIN,从而触发其重新发送ACK。最长为2MSL的时间。这个是最主要的理由。

    还有一个理由是允许老的重复segment在网络中消逝:

     考虑如下一个场景,在A的端口port1和B的端口port2建立了TCP连接,然后关闭了连接。为了保证过一段时间,我们还可以在A的端口port1和B的端口port2之间可以

建立连接。我们应该避免之前的在该连接上的老的分组再出现。为做到这一点,TCP不给处于TIME_WAIT状态的连接发起新的连接。TIME_WAIT的状态持续时间为2MSL,

这样每个方向上的数据的最大存活时间为MSL。这样保证成功建立一个TCP连接时,来自该连接的先前的老的重复分组都已经在网络中消逝了。

原文地址:https://www.cnblogs.com/lovemdx/p/3281581.html