【面试】计算机网络总结2(TCP的三次握手与四次挥手)

点击查看其他内容:

【面试】计算机网络总结1(OSI七层协议+TCP与UDP简介)

【面试】计算机网络总结2(TCP的三次握手与四次挥手)

【面试】计算机网络总结3(TCP的滑动窗口机制+拥塞处理)


​​​​​​​

3 TCP协议详解

3.1 TCP报文段的首部格式

3.1.1 各个字段的意义

3.2 TCP的基本认识

3.3 TCP连接建立(三次握手)

3.3.1 TCP三次握手详解

3.3.2 【问题】:为什么需要三次握手?两次不行吗?

3.4 TCP的连接释放(四次挥手)

3.4.1 TCP四次挥手详解

3.4.2 【问题】为什么挥手需要四次?

 3.4.3【问题】:为什么 TIME_WAIT 等待的时间是 2MSL?

3.4.4 【问题】:为什么需要 TIME_WAIT 状态? 

3.4.5 【问题】:TIME_WAIT 过多有什么危害? 

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


3 TCP协议详解

3.1 TCP报文段的首部格式

TCP虽然是面向字节流的,但是TCP传送的数据单元是报文段,一个TCP报文段分为首部和数据两部分。

TCP的全部功能都体现在其首部中各字段的作用。

TCP报文段的头部格式: 

3.1.1 各个字段的意义

(1)源端口与目的端口:

各占两个字节,分别写入源端口号和目的端口号。TCP的分用功能也是通过端口实现的。

(2)序列号:

占4字节。在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一
次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。

  • 序号范围是【0,2^32 - 1】,共2^32个序号。序号增加到 2^32-1后,下一个序号就又回到 0。TCP是面向字节流的。在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置。首部中的序号字段值则是指的是本报文段所发送的数据的第一个字节的序号。例如,一报文段的序号是301,而接待的数据共有100字节。这就表明:本报文段的数据的第一个字节的序号是301,最后一个字节的序号是400。显然,下一个报文段(如果还有的话)的数据序号应当从401开始,即下一个报文段的序号字段值应为401。这个字段的序号也叫“报文段序号”

(3)确认应答号:

指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决不丢包的问题。

若确认应答号 = N , 则表明:到序号N-1为止的所有数据都已经正确收到。

(4)首部长度(数据偏移):

  • 占4位,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。实际上是用于指出TCP报文段的首部长度。
  • 由于首部中还有长度不确定的选项字段,因此数据偏移字段是必要的。

(5)保留:

  • 占6位,保留为今后使用,但目前应置为0;

(6)控制位:

  • 确认ACK:该位为  1 时,「确认应答」的字段变为有效,(当ACK=0时,确认应答号无效)TCP 规定除了最初建立连接时的  SYN包之外该位必须设置为  1 。
  • 复位RST:该位为  1 时,表示 TCP 连接中出现异常必须强制断开连接。RST置为1还用于拒绝一个非法的报文段或拒绝打开一个连接。
  • 同步SYN:该位为  1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。
  • 当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;
  • 终止FIN:该位为  1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换  FIN 位为 1 的 TCP 段。

(7)紧急URG(URGent):

当URG=1,表明紧急指针字段有效。告诉系统此报文段中有紧急数据;

(8)窗口:

占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受;

(9)检验和:

  • 占2字节,校验首部和数据这两部分;

(10)紧急指针:

  • 占2字节,指出本报文段中的紧急数据的字节数;

(11)选项:

  • 长度可变,定义一些其他的可选的参数

3.2 TCP的基本认识

(1)TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。

1)面向连接:一定是「一对一」才能连接,不能像 UDP 协议可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的;
2)可靠的:无论网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端;
3)字节流:消息是「没有边界」的,所以无论我们消息有多大都可以进行传输。并且消息是「有序的」,当「前一个」消息没有收到的时候,即使它先收到了后面的字节,那么也不能扔给应用层去处理,同时对「重复」的报文会自动丢弃。

(2)TCP连接

用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接

(3)所以,建立一个 TCP 连接是需要客户端与服务器端达成上述三个信息的共识。
Socket:由 IP 地址和端口号组成
序列号:用来解决乱序问题等
窗口大小:用来做流量控制

(4)如何唯一确定一个TCP连接

TCP 四元组可以唯一的确定一个连接,四元组包括如下:
①源地址
②源端口
③目的地址
④目的端口

源地址和目的地址的字段(32位)是在 IP 头部中,作用是通过 IP 协议发送报文给对方主机。
源端口和目的端口的字段(16位)是在 TCP 头部中,作用是告诉 TCP 协议应该把报文发给哪个进程。

(5)有一个 IP 的服务器监听了一个端口,它的 TCP 的最大连接数是多少?
服务器通常固定在某个本地端口上监听,等待客户端的连接请求。
因此,客户端 IP 和 端口是可变的,其理论值计算公式如下:


对 IPv4,客户端的 IP 数最多为  2 的  32 次方,客户端的端口数最多为  2 的  16 次方,也就是服务端单机最大 TCP 连接数,约为  2 的  48 次方。

当然,服务端最大并发 TCP 连接数远不能达到理论上限。

首先主要是文件描述符限制,Socket 都是文件,所以首先要通过  ulimit 配置文件描述符的数目;
另一个是内存限制,每个 TCP 连接都要占用一定内存,操作系统的内存是有限的。

3.3 TCP连接建立(三次握手)

TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手来进行的

在TCP连接建立过程中主要要解决三个问题:

(1)要使每一方能够确定知道对方的存在。

(2)要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项等)

(3)能够对运输实体资源(如缓存带下。连接表中的项目等)进行分配。

TCP连接的建立采用客户服务器方式。主动发起连接建立的应用进程叫做客户,被动等待连接建立的应用进程叫做服务器。

3.3.1 TCP三次握手详解

所谓三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个包。

三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。

一开始,客户端和服务端都处于  CLOSED 状态。先是服务端主动监听某个端口,处于  LISTEN状态

注意,客户端主动打开连接,服务端被动打开连接。

客户端会随机初始化序号( client_isn =x),将此序号置于 TCP 首部的「序号」字段中,同时把SYN 标志位置为  1 ,表示  SYN 报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于  SYN-SENT (同步已发送)状态

服务端收到客户端的  SYN 报文后,首先服务端也随机初始化自己的序号( server_isn =y),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入  client_isn +1 , 接着把  SYN 和  ACK 标志位置为  1 。最后把该报文(SYN+ACK报文段)发给客户端该报文也不包含应用层数据,之后服务端处于  SYN-RCVD(同步收到) 状态

客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部ACK 标志位置为  1 (SYN标志位为0)其次「确认应答号」字段填入  server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带客户到服务器的数据,之后客户端处于  ESTABLISHED 状态服务器收到客户端的应答报文后,也进入  ESTABLISHED 状态。

【从上面的过程可以发现第三次握手是可以携带数据的,前两次握手是不可以携带数据的,这也是面试常问的题。】

一旦完成三次握手,双方都处于  ESTABLISHED 状态,此时连接就已建立完成,客户端和服务端就可以相互发送数据了。

3.3.2 【问题】:为什么需要三次握手?两次不行吗?

 为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

具体例子:“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。

假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。

例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”

接下来以三个方面分析三次握手的原因:
①三次握手才可以阻止重复历史连接的初始化(主要原因)
②三次握手才可以同步双方的初始序列号
③三次握手才可以避免资源浪费

原因一:避免历史连接

简单来说,三次握手的首要原因是为了防止旧的重复连接初始化造成混乱。
网络环境是错综复杂的,往往并不是如我们期望的一样,先发送的数据包,就先到达目标主机,反而它很骚,可能会由于网络拥堵等乱七八糟的原因,会使得旧的数据包,先到达目标主机,那么这种情况下TCP 三次握手是如何避免的呢?

客户端连续发送多次 SYN 建立连接的报文,在网络拥堵情况下:

一个「旧 SYN 报文」比「最新的 SYN 」 报文早到达了服务端;
那么此时服务端就会回一个  SYN + ACK 报文给客户端;
客户端收到后可以根据自身的上下文,判断这是一个历史连接(序列号过期或超时),那么客户端就会发送  RST 报文给服务端,表示中止这一次连接。

如果是两次握手连接,就不能判断当前连接是否是历史连接,三次握手则可以在客户端(发送方)准备发送第三次报文时,客户端因有足够的上下文来判断当前连接是否是历史连接:

如果是历史连接(序列号过期或超时),则第三次握手发送的报文是  RST 报文,以此中止历史连接;
如果不是历史连接,则第三次发送的报文是  ACK 报文,通信双方就会成功建立连接;

所以,TCP 使用三次握手建立连接的最主要原因是防止历史连接初始化了连接

原因二:同步双方初始序列号

TCP 协议的通信双方, 都必须维护一个「序列号」, 序列号是可靠传输的一个关键因素,它的作用:
·接收方可以去除重复的数据;
·接收方可以根据数据包的序列号按序接收;
·可以标识发送出去的数据包中, 哪些是已经被对方收到的;

可见,序列号在 TCP 连接中占据着非常重要的作用,所以当客户端发送携带「初始序列号」的  SYN报文的时候,需要服务端回一个  ACK 应答报文,表示客户端的 SYN 报文已被服务端成功接收,那当服务端发送「初始序列号」给客户端的时候,依然也要得到客户端的应答回应,这样一来一回,才能确保双方的初始序列号能被可靠的同步。

四次握手其实也能够可靠的同步双方的初始化序号,但由于第二步和第三步可以优化成一步,所以就成了「三次握手」。

而两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。

原因三:避免资源浪费

如果只有「两次握手」,当客户端的  SYN 请求连接在网络中阻塞,客户端没有接收到  ACK 报文,就会重新发送  SYN ,由于没有第三次握手,服务器不清楚客户端是否收到了自己发送的建立连接的ACK 确认信号,所以每收到一个  SYN 就只能先主动建立一个连接,这会造成什么情况呢?

如果客户端的  SYN 阻塞了,重复发送多次  SYN 报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。

即两次握手会造成消息滞留情况下,服务器重复接受无用的连接请求  SYN 报文,而造成重复分配资源。

总结:

TCP 建立连接时,通过三次握手能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。

不使用「两次握手」和「四次握手」的原因:

「两次握手」:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

为什么客户端和服务端的初始序列号 ISN 是不相同的?

如果一个已经失效的连接被重用了,但是该旧连接的历史报文还残留在网络中,如果序列号相同,那么就无法分辨出该报文是不是历史报文,如果历史报文被新的连接接收了,则会产生数据错乱。

所以,每次建立连接前重新初始化一个序列号主要是为了通信双方能够根据序号将不属于本连接的报文段丢弃。

另一方面是为了安全性,防止黑客伪造的相同序列号的 TCP 报文被对方接收。

初始序列号 ISN 是如何随机产生的?

起始  ISN 是基于时钟的,每 4 毫秒 + 1,转一圈要 4.55 个小时。
RFC1948 中提出了一个较好的初始化序列号 ISN 随机生成算法。

ISN = M + F (localhost, localport, remotehost, remoteport)

M 是一个计时器,这个计时器每隔 4 毫秒加 1。
F 是一个 Hash 算法,根据源 IP、目的 IP、源端口、目的端口生成一个随机数值。要保证Hash 算法不能被外部轻易推算得出,用 MD5 算法是一个比较好的选择。

3.4 TCP的连接释放(四次挥手)

 TCP 断开连接是通过四次挥手方式。

TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),也叫做改进的三次握手。客户端或服务器均可主动发起挥手动作。

3.4.1 TCP四次挥手详解

  • 第一次挥手(FIN=1,seq=x)

主机1(可以是客户端,也可以是服务器端),设置seq=u(等于前面已传送过数据的最后一个字节的序号+1),向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;等待主机2的确认。

  • 第二次挥手(ACK=1,ACKnum=x+1)

主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknnum=u+1,这个报文段自己的序号是v,主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;主机2进入CLOSE-WAIT(关闭等待)状态。

TCP服务器进程此时应该通知高层应用进程,因此从主机1到主机2这个方向的连接就释放了,此时TCP连接处于半关闭状态(half-close)。此时A没有数据要发了,但若B要发送数据,A仍然要接收。

  • 第三次挥手(FIN=1,seq=y)

主机2向主机1发送FIN报文段,(确认号为u+1,自己的报文序号为w)请求关闭连接,同时主机2进入LAST_ACK (最后确认)状态。

  • 第四次挥手(ACK=1,ACKnum=y+1)

主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段(置为1),确认号ack = w+1,自己报文段的序号为u+1,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,

主机 1 等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。(MSL称为最长报文段寿命)

你可以看到,每个方向都需要一个 FIN 和一个 ACK,因此通常被称为四次挥手。

这里一点需要注意是:主动关闭连接的,才有 TIME_WAIT 状态。

3.4.2 【问题】为什么挥手需要四次?

再来回顾下四次挥手双方发  FIN 包的过程,就能理解为什么需要四次了。

关闭连接时,客户端向服务端发送  FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。

服务器收到客户端的  FIN 报文时,先回一个  ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送  FIN 报文给客户端来表示同意现在关闭连接。

从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的  ACK 和  FIN 一般都会分开发送,从而比三次握手导致多了一次。

 3.4.3【问题】:为什么 TIME_WAIT 等待的时间是 2MSL?

MSL 是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为 TCP 报文基于是 IP 协议的,而 IP 头中有一个  TTL 字段,是 IP 数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减 1,当此值为 0 则数据报将被丢弃,同时发送 ICMP 报文通知源主机。

MSL 与 TTL 的区别: MSL 的单位是时间,而 TTL 是经过路由跳数。所以 MSL 应该要大于等于 TTL消耗为 0 的时间,以确保报文已被自然消亡。

TIME_WAIT 等待 2 倍的 MSL,比较合理的解释是: 网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间。

比如如果被动关闭方没有收到断开连接的最后的 ACK 报文,就会触发超时重发 Fin 报文,另一方接收到 FIN 后,会重发 ACK 给被动关闭方, 一来一去正好 2 个 MSL。

2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务端,客户端又接收到了服务端重发的 FIN 报文,那么 2MSL 时间将重新计时。

3.4.4 【问题】:为什么需要 TIME_WAIT 状态? 

主动发起关闭连接的一方,才会有  TIME-WAIT 状态。

需要 TIME-WAIT 状态,主要是两个原因:

①防止具有相同「四元组」的「旧」数据包被收到;
②保证「被动关闭连接」的一方能被正确的关闭,即保证最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭;

原因一:防止旧连接的数据包

假设 TIME-WAIT 没有等待时间或时间过短,被延迟的数据包抵达后会发生什么呢?

如上图黄色框框服务端在关闭连接之前发送的  SEQ = 301 报文,被网络延迟了。

这时有相同端口的 TCP 连接被复用后,被延迟的  SEQ = 301 抵达了客户端,那么客户端是有可能正常接收这个过期的报文,这就会产生数据错乱等严重的问题。

所以,TCP 就设计出了这么一个机制,经过  2MSL 这个时间,足以让两个方向上的数据包都被丢弃,使得原来连接的数据包在网络中都自然消失,再出现的数据包一定都是新建立连接所产生的。

原因二:保证连接正确关闭

也就是说,TIME-WAIT 作用是等待足够的时间以确保最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭。

假设 TIME-WAIT 没有等待时间或时间过短,断开连接会造成什么问题呢?

如上图红色框框客户端四次挥手的最后一个  ACK 报文如果在网络中被丢失了,此时如果客户端TIME-WAIT 过短或没有,则就直接进入了  CLOSED 状态了,那么服务端则会一直处在LASE_ACK 状态。

当客户端发起建立连接的  SYN 请求报文后,服务端会发送  RST 报文给客户端,连接建立的过程就会被终止。

如果 TIME-WAIT 等待足够长的情况就会遇到两种情况:

服务端正常收到四次挥手的最后一个  ACK 报文,则服务端正常关闭连接。
服务端没有收到四次挥手的最后一个  ACK 报文时,则会重发  FIN 关闭连接报文并等待新的ACK 报文。

所以客户端在  TIME-WAIT 状态等待  2MSL 时间后,就可以保证双方的连接都可以正常的关闭。

TIME_WAIT的危害

https://blog.csdn.net/weixin_30537451/article/details/97055809

在高并发短连接的TCP服务器上,当服务器处理完请求后主动请求关闭连接,这样服务器上会有大量的连接处于TIME_WAIT状态,服务器维护每一个连接需要一个socket,也就是每个连接会占用一个文件描述符,而文件描述符的使用是有上限的,如果持续高并发,会导致一些连接失败。

还有一种情况,假设假设假设,今天双十一,这是一台Tmall的服务器,因为一些原因,服务器进程挂掉了,退出了,由于是服务器主动关闭连接,因此会有TIME_WAIT状态存在,也就意味着服务器进程想立即重启,但是起不来,因为端口(可能是80)还被之前处于TIME_WAIT的连接占用着,如果TIME_WAIT状态维持60秒,60秒服务器都起不来,双十一,啧啧。

如何避免TIME_WAIT的危害?

可设置套接字选项为SO_REUSEADDR,该选项的意思是,告诉操作系统,如果端口忙,但占用该端口TCP连接处于TIME_WAIT状态,并且套接字选项为SO_REUSEADDR,则该端口可被重用。如果TCP连接处于其他状态,依然返回端口被占用。该选项对服务程序重启非常有用。

3.4.5 【问题】:TIME_WAIT 过多有什么危害? 

如果服务器有处于 TIME-WAIT 状态的 TCP,则说明是由服务器方主动发起的断开请求。

过多的 TIME-WAIT 状态主要的危害有两种:

第一是内存资源占用;
第二是对端口资源的占用,一个 TCP 连接至少消耗一个本地端口;

第二个危害是会造成严重的后果的,要知道,端口资源也是有限的,一般可以开启的端口为  32768~61000 ,也可以通过如下参数设置指定  net.ipv4.ip_local_port_range.

如果发起连接一方的 TIME_WAIT 状态过多,占满了所有端口资源,则会导致无法创建新连接。

客户端受端口资源限制:
客户端TIME_WAIT过多,就会导致端口资源被占用,因为端口就65536个,被占满就会导致无法创建新的连接。

服务端受系统资源限制:
由于一个四元组表示 TCP 连接,理论上服务端可以建立很多连接,服务端确实只监听一个端口 但是会把连接扔给处理线程,所以理论上监听的端口可以继续监听。但是线程池处理不了那么多一直不断的连接了。所以当服务端出现大量 TIME_WAIT 时,系统资源被占满时,会导致处理不过来新的连接。

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

TCP 有一个机制是保活机制。这个机制的原理是这样的:

定义一个时间段(保活计时器),在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。

在 Linux 内核可以有对应的参数可以设置保活时间、保活探测的次数、保活探测的时间间隔,以下都为默认值:

tcp_keepalive_time=7200:表示保活时间是 7200 秒(2小时),也就 2 小时内如果没有任何连接相关的活动,则会启动保活机制
tcp_keepalive_intvl=75:表示每次检测间隔 75 秒;
tcp_keepalive_probes=9:表示检测 9 次无响应,认为对方是不可达的,从而中断本次的连接。

也就是说在 Linux 系统中,最少需要经过 2 小时 11 分 15 秒才可以发现一个「死亡」连接。

如果开启了 TCP 保活,需要考虑以下几种情况:

第一种,对端程序是正常工作的。当 TCP 保活的探测报文发送给对端, 对端会正常响应,这样 TCP 保活时间会被重置,等待下一个 TCP 保活时间的到来。

第二种,对端程序崩溃并重启。当 TCP 保活的探测报文发送给对端后,对端是可以响应的,但由于没有该连接的有效信息,会产生一个 RST 报文,这样很快就会发现 TCP 连接已经被重置。

第三种,是对端程序崩溃,或对端由于其他原因导致报文不可达。当 TCP 保活的探测报文发送给对端后,石沉大海,没有响应,连续几次,达到保活探测次数后,TCP 会报告该 TCP 连接已经死亡。

注:文章内容来自谢希仁《计算机网络第六版》 与 微信公众号:小林coding图解系列 与 多来源 计网ppt 

猜你喜欢

转载自blog.csdn.net/paranior/article/details/115209589
今日推荐