<返回更多

多图详解TCP三次握手和四次挥手(有限状态机)

2020-11-13    
加入收藏

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的 RFC 793 定义,是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。

互联网络与单个网络有很大的不同,因为互联网络的不同部分可能有截然不同的拓扑结构、带宽、延迟、数据包大小和其他参数。TCP 的设计目标是能够动态地适应互联网络的这些特性,而且具备面对各种故障时的健壮性。

应用层向 TCP 层发送用于网间传输的、用 8 位字节表示的数据流,然后 TCP 把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制)。之后 TCP 把结果包传给 IP 层,由它来通过网络将包传送给接收端实体的 TCP 层。TCP 为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP 用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。

TCP 消息头

 

多图详解TCP三次握手和四次挥手(有限状态机)

 

下面对每个字段含义进行解释

TCP 三次握手

TCP是一个面向连接的协议,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接,建立一条连接有以下过程。

这三个报文段完成连接的建立,这个过程成为三次握手。

多图详解TCP三次握手和四次挥手(有限状态机)

 

SYN 攻击

在三次握手过程中,Server 发送 SYN-ACK 之后,收到 Client 的 ACK 之前的 TCP 连接称为半连接(half-open connect),此时 Server 处于 SYN_RCVD 状态,当收到 ACK 后,Server 转入 ESTABLISHED 状态。

SYN 攻击就是 Client 在短时间内伪造大量不存在的 IP 地址,并向 Server 不断地发送 SYN 包,Server 回复确认包,并等待 Client 的确认,由于源地址是不存在的,因此,Server 需要不断重发直至超时,这些伪造的 SYN 包将长时间占用未连接队列,导致正常的 SYN 请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。

SYN 攻击时一种典型的 DDoS 攻击,检测 SYN 攻击的方式非常简单,即当 Server 上有大量半连接状态且源 IP 地址是随机的,则可以断定遭到 SYN 攻击了。

解决方案:

当开放了一个 TCP 端口后,该端口就处于 Listening 状态,不停地监视发到该端口的 Syn 报文,

一旦接收到 Client 发来的 Syn 报文,就需要为该请求分配一个 TCB(Transmission Control Block),并返回一个 SYN ACK 命令,立即转为 SYN-RECEIVED 即半开连接状态。

通常一个 TCB 至少需要 280 个字节,在某些操作系统中 TCB 甚至需要 1300 个字节,而某些操作系统在 SOCK 的实现上最多可开启 512 个半开连接。

消耗服务器资源主要是因为当 SYN 数据报文一到达,系统立即分配 TCB,从而占用了资源。

解决:

收到 SYN 数据报文时不急于去分配TCB,而是先回应一个SYN ACK报文,并在一个专用HASH表(Cache)中保存这种半开连接信息,直到收到正确的回应ACK报文再分配TCB。

TCP终止连接过程(四次挥手)

多图详解TCP三次握手和四次挥手(有限状态机)

 

  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为 seq=u(等于前面已经传送过来的数据的最后一个字节的序号加 1),此时,客户端进入 FIN-WAIT-1(终止等待1)状态。 TCP 规定,FIN报文段即使不携带数据,也要消耗一个序号。
  2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号 seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个 CLOSE-WAIT 状态持续的时间。
  3. 客户端收到服务器的确认请求后,此时,客户端就进入 FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
  4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为 seq=w,此时,服务器就进入了 LAST-ACK(最后确认)状态,等待客户端的确认。
  5. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是 seq=u+1,此时,客户端就进入了 TIME-WAIT(时间等待)状态。注意此时 TCP连接还没有释放,必须经过 2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入 CLOSED 状态。
  6. 服务器只要收到了客户端发出的确认,立即进入 CLOSED 状态。同样,撤销 TCB 后,就结束了这次的 TCP 连接。可以看到,服务器结束 TCP 连接的时间要比客户端早一些。

TCP 状态机

多图详解TCP三次握手和四次挥手(有限状态机)

 

 

上图是 TCP 的状态机。

  1. CLOSED:状态时初始状态。
  2. LISTEN:被动打开,服务器端的 状态变为 LISTEN (监听)。被动打开的概念:连接的一端的应用程序通知操作系统,希望建立一个传入的连接。这时候操作系统为连接的这一端建立一个连接。与之对应的是主动连接:应用程序通过主动打开请求来告诉操作系统建立一个连接。
  3. SYNRECVD:服务器端收到 SYN 后,状态为 SYN;发送 SYN ACK;
  4. SYN_SENTY:应用程序发送 SYN 后,状态为 SYN_SENT;
  5. ESTABLISHED:SYNRECVD 收到 ACK 后,状态为 ESTABLISHED; SYN_SENT 在收到 SYN ACK,发送 ACK,状态为 ESTABLISHED;
  6. CLOSE_WAIT:服务器端在收到 FIN 后,发送 ACK,状态为 CLOSE_WAIT;如果此时服务器端还有数据需要发送,那么就发送,直到数据发送完毕;此时,服务器端发送FIN,状态变为 LAST_ACK;
  7. FIN_WAIT_1:应用程序端发送 FIN,准备断开 TCP 连接;状态从 ESTABLISHED -> FIN_WAIT_1;
  8. FIN_WAIT_2:应用程序端只收到服务器端得 ACK 信号,并没有收到FIN信号;说明服务器端还有数据传输,那么此时为半连接;
  9. TIME_WAIT:有两种方式进入该状态:FIN_WAIT_1进入:此时应用程序端口收到 FIN+ACK(而不是像 FIN_WAIT_2 那样只收到 ACK,说明数据已经发送完毕)并向服务器端口发送 ACK;FIN_WAIT_2进入:此时应用程序端口收到了 FIN,然后向服务器端发送 ACK;TIME_WAIT 是为了实现 TCP 全双工连接的可靠性关闭,用来重发可能丢失的 ACK 报文;需要持续 2 个 MSL (最大报文生存时间):假设应用程序端口在进入 TIME_WAIT后,2 个 MSL 时间内并没有收到FIN,说明应用程序最后发出的 ACK 已经收到了;否则,会在 2 个 MSL 内在此收到ACK报文;

客户端应用程序的状态迁移图

客户端的状态可以用如下的流程来表示:

CLOSED -> SYN_SENT -> ESTABLISHED -> FIN_WAIT_1 -> FIN_WAIT_2 -> TIME_WAIT -> CLOSED

以上流程是在程序正常的情况下应该有的流程,从书中的图中可以看到,在建立连接时,当客户端收到 SYN 报文的 ACK 以后,客户端就打开了数据交互地连接。而结束连接则通常是客户端主动结束的,客户端结束应用程序以后,需要经历 FIN_WAIT_1,FIN_WAIT_2 等状态,这些状态的迁移就是前面提到的结束连接的四次握手。

服务器的状态迁移图

服务器的状态可以用如下的流程来表示:

CLOSED -> LISTEN -> SYN 收到 -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED

在建立连接的时候,服务器端是在第三次握手之后才进入数据交互状态,而关闭连接则是在关闭连接的第二次握手以后(注意不是第四次)。而关闭以后还要等待客户端给出最后的ACK 包才能进入初始的状态。

其他状态迁移

书中的图还有一些其他的状态迁移,这些状态迁移针对服务器和客户端两方面的总结如下

2 MSL 等待状态

书中给的图里面,有一个 TIME_WAIT 等待状态,这个状态又叫做 2 MSL 状态,说的是在 TIME_WAIT2 发送了最后一个 ACK 数据报以后,要进入 TIME_WAIT 状态,这个状态是防止最后一次握手的数据报没有传送到对方那里而准备的(注意这不是四次握手,这是第四次握手的保险状态)。这个状态在很大程度上保证了双方都可以正常结束,但是,问题也来了。

由于插口的 2MSL 状态(插口是IP和端口对的意思,socket),使得应用程序在 2 MSL 时间内是无法再次使用同一个插口的,对于客户程序还好一些,但是对于服务程序,例如httpd,它总是要使用同一个端口来进行服务,而在 2 MSL 时间内,启动 httpd 就会出现错误(插口被使用)。为了避免这个错误,服务器给出了一个平静时间的概念,这是说在 2 MSL 时间内,虽然可以重新启动服务器,但是这个服务器还是要平静的等待 2 MSL 时间的过去才能进行下一次连接。

FIN_WAIT_2 状态

这就是著名的半关闭的状态了,这是在关闭连接时,客户端和服务器两次握手之后的状态。在这个状态下,应用程序还有接受数据的能力,但是已经无法发送数据,但是也有一种可能是,客户端一直处于 FIN_WAIT_2 状态,而服务器则一直处于 WAIT_CLOSE 状态,而直到应用层来决定关闭这个状态。

RST,同时打开和同时关闭

RST 是另一种关闭连接的方式,应用程序应该可以判断 RST 包的真实性,即是否为异常中止。而同时打开和同时关闭则是两种特殊的 TCP 状态,发生的概率很小。

常见面试题

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?

答:因为当 Server 端收到 Client 端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。但是关闭连接时,当 Server 端收到 FIN 报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个 ACK 报文,告诉 Client 端,"你发的 FIN 报文我收到了"。只有等到我 Server 端所有的报文都发送完了,我才能发送 FIN 报文,因此不能一起发送。故需要四步握手。

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

虽然按道理,四个报文都发送完毕,我们可以直接进入 CLOSE 状态了,但是我们必须假象网络是不可靠的,有可以最后一个 ACK 丢失。所以TIME_WAIT状态就是用来重发可能丢失的 ACK 报文。在 Client 发送出最后的 ACK 回复,但该 ACK 可能丢失。Server 如果没有收到 ACK,将不断重复发送 FIN 片段。所以 Client 不能立即关闭,它必须确认 Server 接收到了该ACK。Client 会在发送出ACK 之后进入到 TIME_WAIT 状态。Client 会设置一个计时器,等待 2MSL 的时间。如果在该时间内再次收到FIN,那么 Client 会重发 ACK 并再次等待2 MSL。所谓的 2 MSL 是两倍的 MSL(Maximum Segment Lifetime)。MSL 指一个片段在网络中最大的存活时间,2MSL 就是一个发送和一个回复所需的最大时间。如果直到 2 MSL,Client 都没有再次收到 FIN,那么 Client 推断 ACK 已经被成功接收,则结束 TCP 连接。

【问题3】为什么不能用两次握手进行连接?

3 次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机 S 和 C 之间的通信,假定 C 给 S 发送一个连接请求分组,S 收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S 认为连接已经成功地建立了,可以开始发送数据分组。可是,C 在 S 的应答分组在传输中被丢失的情况下,将不知道 S 是否已准备好,不知道 S 建立什么样的序列号,C 甚至怀疑 S 是否收到自己的连接请求分组。在这种情况下,C 认为连接还未建立成功,将忽略 S 发来的任何数据分组,只等待连接确认应答分组。而 S 在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

【问题4】如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP 还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为 2 小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔 75 秒钟发送一次。若一连发送 10 个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接

树林美丽、幽暗而深邃,但我有诺言尚待实现,还要奔行百里方可沉睡。 -- 罗伯特·弗罗斯特

来源:https://www.cnblogs.com/huansky/p/13951567.html

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>