TCP的建立与终止——三次握手、四次挥手

news2024/10/18 13:02:50

目录

1. UDP和TCP的区别

2. TCP概述

3. TCP连接的建立(三次握手)

3.1 为什么TCP客户端最后还要发送一次确认?

3.2 什么是半连接队列?

3.3 半连接队列被填满或遇到SYN洪泛攻击是如何处理?

3.4 三次握手过程中可以携带数据吗?

3.5 ISN(Initial Sequence Number)是固定的吗?

3.6 一个包数据可能会被拆成多个包发送,如何处理丢包问题?

3.7 三次握手总结

4. 四次挥手

4.1 为什么客户端最后还要等待2MSL?

4.2 为什么建立连接是三次握手,关闭连接确是四次挥手?

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


1. UDP和TCP的区别

UDP:在传送数据前不需要先建立连接,远地的主机在收到UDP报文后也不需要给出任何确认。虽然UDP不提供可靠交付,但是正是因为这样,省去和很多的开销,使得它的速度比较快,比如一些对实时性要求较高的服务,就常常使用的是UDP,比如视频流、在线游戏和实时语音通话等。

TCP:提供面向连接的服务,在传送数据之前必须先建立连接,数据传送完成后要释放连接。因此TCP是一种可靠的的运输服务,但是正因为这样,不可避免的增加了许多的开销,比如确认,流量控制等。常应用于网页浏览、电子邮件、文件传输等。

二者的主要区别

  • 连接方式:TCP是连接导向,UDP是无连接
  • 可靠性:TCP提供可靠传输,UDP不保证可靠性
  • 数据传输:TCP面向字节流,UDP面向数据报
  • 性能:UDP通常更快,但不保证数据的正确性和顺序,而TCP更稳定但相对较慢

2. TCP概述

TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种断点我们叫作套接字(socket),它的定义为端口号拼接到IP地址即构成了套接字,例如,若IP地址为192.3.4.16 而端口号为80,那么得到的套接字为192.3.4.16:80。

3. TCP连接的建立(三次握手)

三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。

注意,三次握手必须是一方主动打开,另一方被动打开的

首先,TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,而客户端处于Closed状态,服务器处于LISTEN(监听)状态。

然后,进行三次握手

1)第一次握手:首先客户端向服务器发送一段SYN(同步)报文,并指明客户端是初始化序列号是ISN,其中

  • 首部的同步位为SYN=1,表示“请求建立新连接”;
  • 序号为seq=x(x一般位1);
  • SYN=1的报文段不能携带数据,但要消耗掉一个序号;
  • 随后客户端进入SYN-SENT阶段。

图片来源:https://blog.csdn.net/kking_edc/article/details/109480520

注:SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号

2)第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN + 1 作为ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_RCVD 的状态。

在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y。

不要将确认序号ack与标志位中的ACK搞混了
确认方ack=发起方Seq+1,两端配对

图片来源:https://blog.csdn.net/kking_edc/article/details/109480520

注:SYN+ACK报文也不能携带数据,但是同样要消耗一个序号

3)第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接。

确认报文段ACK=1,确认号ack=y+1,序号seq=x+1(初始为seq=x,第二个报文段所以要+1),ACK报文段可以携带数据,不携带数据则不消耗序号。

图片来源:https://blog.csdn.net/kking_edc/article/details/109480520

注:ACK报文段可以携带数据,但是如果不携带数据则不消耗序号

3.1 为什么TCP客户端最后还要发送一次确认?

一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。

如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,此时,客户端认为自己只有一个连接,但是服务器认为有两个连接,导致不必要的错误和资源的浪费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

那么如何通过三次握手解决该问题?参考下图

图片来源:https://blog.csdn.net/kking_edc/article/details/109480520

  • 如果一个「旧 SYN 报文」比「最新的 SYN」 报文早到达了服务端(一次握手),那么此时服务端就会回一个 SYN + ACK (二次握手)报文给客户端,此报文中的确认号是 91(90+1)。
  • 客户端收到后,发现自己期望收到的确认号应该是 100 + 1,而不是 90 + 1,于是就会回 RST 报文(三次握手)。
  • 服务端收到 RST 报文后,就会释放连接。
  • 后续最新的 SYN 抵达了服务端后,客户端与服务端就可以正常的完成三次握手了。
当第三次握手失败时,服务器并不会重传ack报文,而是直接发送RST报文段,进入CLOSED状态。这样做的目的是为了防止SYN洪泛攻击。

3.2 什么是半连接队列?

服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。简单来说就是,半连接队列用于存储那些已经通过了TCP三次握手的前两次握手(即接收了客户端的SYN,并回复了SYN-ACK)但还未完成第三次握手的连接。

图片来源:https://blog.csdn.net/kking_edc/article/details/109480520

全连接队列:已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。

半连接队列的工作原理

  • 当客户端向服务器发送SYN请求(第一次握手)时,服务器会为这个请求分配资源,并将这个连接放入半连接队列中,同时向客户端回复SYN-ACK(第二次握手)。
  • 客户端收到SYN-ACK后,回复ACK(第三次握手),服务器收到ACK后,才会将该连接从半连接队列移到全连接队列,并认为该连接已经完全建立,可以开始通信。
  • 如果客户端没有在超时时间内回复ACK(如因网络延迟或故意攻击),服务器会在超时后将这个半连接从队列中移除。

针对上面最后一条,如果服务器发送完SYN-ACK包,未收到客户确认包,服务器将进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。

每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s……

3.3 半连接队列被填满或遇到SYN洪泛攻击是如何处理?

当半连接队列被填满或遇到SYN洪泛攻击时,服务器的TCP连接管理会受到严重影响。这种情况下,服务器可能无法正常接收新的连接请求,导致拒绝服务。

1)半连接队列被填满

半连接队列在上面的问题中已经详细说过,它是用于存储那些完成了TCP三次握手的前两次握手(SYN和SYN-ACK),但还未完成第三次握手(ACK)的连接,它的容量是有限的,由服务器的配置决定。

  • 当客户端向服务器发送SYN请求时,服务器会将这个连接放入半连接队列,并向客户端发送SYN-ACK响应。
  • 如果半连接队列中的连接数量超过了其容量上限,就表示队列已被填满。
  • 当队列被填满后,服务器将无法处理新的SYN请求,因为它已经没有空间存储新的半连接。这时,服务器可能会丢弃新的SYN包,导致新的连接无法建立。

半连接队列填满的原因

  • 正常情况下:如果服务器的负载很高,并且有大量合法客户端同时尝试连接,半连接队列可能会短暂填满。
  • 攻击情况下:在SYN洪泛攻击中,攻击者故意发送大量的SYN请求,并不回复ACK,以使半连接队列快速填满,从而导致服务器无法接受新的合法连接。

2)什么是SYN洪泛攻击?

服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。

SYN攻击利用TCP协议的三次握手过程来耗尽服务器的资源,Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。

如何应对?

1)检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstat 命令来检测 SYN 攻击。

netstat -n -p TCP | grep SYN_RECV

2)SYN Cookie:当服务器检测到半连接队列即将被填满或受到SYN洪泛攻击时,通过使用SYN Cookie解决,在linux中通过tcp_syncookies参数来应对这件事:

  • 服务器不在半连接队列中分配空间,而是将序列号经过加密算法生成一个Cookie,并发送给客户端。
  • 客户端回复的ACK中会带上这个SYN Cookie。服务器通过这个Cookie验证连接的合法性,从而不依赖半连接队列的大小。
  • 这种方式即使在遭受攻击时,也能确保服务器继续接收并验证新的连接请求。
千万别用 tcp_syncookies来处理正常的大负载的连接的情况。因为, SYN Cookie是妥协版的TCP协议,并不严谨。对于正常的请求,你应该调整三个TCP参数可供你选择,第一个是: tcp_synack_retries可以用他来减少重试次数(服务器发出);第二个是: tcp_max_syn_backlog,可以增大SYN连接数;第三个是: tcp_abort_on_overflow处理不过来干脆就直接拒绝连接了。

3.4 三次握手过程中可以携带数据吗?

其实第三次握手的时候,理论上是可以携带数据的。但是,第一次、第二次握手不可以携带数据

为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。

也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态(服务器此时还未处于 ESTABLISHED 状态)。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。

虽然第三次握手理论上可以携带数据,但通常不这样做,这是因为:

  • 确保连接的稳定性:三次握手的主要目的是建立一个可靠的连接,以确保双方的发送和接收能力正常。如果在连接建立之前就传输数据,而连接建立失败,那么这些数据就可能丢失。
  • 安全性:三次握手阶段的数据传输还没有经过完整的安全和可靠性验证,因此传输数据可能不安全。
  • 协议规范:标准的TCP协议并不推荐在SYN和SYN-ACK包中携带数据,以减少复杂性,并确保握手的过程专注于连接建立。

例外:

虽然标准的三次握手过程不携带数据,但有一些TCP优化技术允许在三次握手的第三次握手(ACK包)中携带数据。这种优化被称为“TCP Fast Open”

  • TCP Fast Open (TFO) 是一种优化技术,可以在第三次握手中携带数据。这需要客户端和服务器都支持TFO,并且客户端在第一次握手时发送一个TFO Cookie。
  • 当客户端和服务器在后续的连接中都使用这个Cookie时,客户端可以在三次握手的过程中携带数据,从而减少延迟。

总结:

TCP三次握手过程中客户端可以携带数据,但为了标准性一般不这么做,第一次、第二次握手不可以携带数据。但是在一些优化情况下(如TCP Fast Open),可以在第三次握手过程中携带数据,提高传输效率。

3.5 ISN(Initial Sequence Number)是固定的吗?

对于连接的3次握手,主要是要初始化Sequence Number 的初始值。通信的双方要互相通知对方自己的初始化的Sequence Number(缩写为ISN:Inital Sequence Number)。这个号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输的问题而乱序(TCP会用这个序号来拼接数据).

当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN。ISN可以看作是一个32比特的计数器,每4ms加1 。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它做错误的解释。

三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的

3.6 一个包数据可能会被拆成多个包发送,如何处理丢包问题?

在TCP协议中,当一个数据包过大或者需要适应网络传输情况时,数据可能会被拆成多个包发送,一般通过数据拆分与组装对数据进行处理。

  • 当数据被拆分成多个TCP包发送时,TCP会为每个包分配一个序列号(Sequence Number),这些序列号用于标识每个包在整个数据流中的位置。
  • 接收端根据序列号来重组这些包,以确保所有数据按照正确的顺序重新组装。

该序列号和握手过程中的ISN有紧密的关系,一旦三次握手完成,ISN就成为后续数据传输中序列号的基准点:

  • 客户端发送的第一个数据包:客户端发送的第一个数据包的序列号是ISN_C + 1,这个“+1”是因为ISN本身被用来标识SYN包。
  • 服务器发送的第一个数据包:同样,服务器发送的第一个数据包的序列号是ISN_S + 1。
  • 从这个基准序列号(ISN + 1)开始,后续的数据包序列号会递增,增量为每个数据包的字节数

下面介绍如何对数据包进行检测以及处理:

丢包的检测与处理机制:

a. 确认机制(ACK)

  • 当接收端成功接收到一个数据包时,它会返回一个 确认包(接收端需要回复一个ACK=序列号+长度,确定该数据包已成功被接收)给发送端,告知其接收到的数据序列号。
  • 如果发送端在一定的时间内(超时时间)没有收到某个数据包的ACK(接收端发送的ACK=序列号+长度,并发送端会将其作为下一数据包的起始序列号),就会认为该数据包可能丢失了

b. 超时重传(Timeout Retransmission)

  • 当发送端没有在预定的超时时间内收到ACK时,它会认为这个数据包丢失了,并重传这个包。
  • TCP使用动态超时重传机制,即根据网络的延迟情况调整超时时间,以提高丢包检测的效率。

c. 快速重传(Fast Retransmit)

  • 如果接收端收到一个数据包,但发现中间的一个数据包丢失了(例如收到序列号为1、3、4的包,但序列号2的包丢失),它会重复发送对序列号2的重复确认(Duplicate ACK)
  • 当发送端收到连续的三个重复确认(Triple Duplicate ACKs)时,就会触发快速重传机制,立即重发那个丢失的数据包,而不必等待超时。

3.7 三次握手总结

三次握手建立连接的首要目的是同步序列号。只有同步了序列号才有可靠的传输,TCP 协议的许多特性都是依赖序列号实现的,比如流量控制、消息丢失后的重发等等,这也是三次握手中的报文被称为 SYN 的原因,因为 SYN 的全称就叫做 Synchronize Sequence Numbers

a. 客户端

客户端发送 SYN 开启了三次握手,之后客户端连接的状态是 SYN_SENT,然后等待服务器回复 ACK 报文。正常情况下,服务器会在几毫秒内返回 ACK,但如果客户端迟迟没有收到 ACK 会怎么样呢?客户端会重发 SYN,重试的次数由 tcp_syn_retries 参数(在3.3中详细说过该参数以及yncookies)控制,默认是 6 次:

net.ipv4.tcp_syn_retries = 6

第 1 次重试发生在 1 秒钟后,接着会以翻倍的方式在第 2、4、8、16、32 秒共做 6 次重试,最后一次重试会等待 64 秒,如果仍然没有返回 ACK,才会终止三次握手。所以,总耗时是 1+2+4+8+16+32+64=127 秒,超过 2 分钟。

如果这是一台有明确任务的服务器,可以根据网络的稳定性和目标服务器的繁忙程度修改重试次数,调整客户端的三次握手时间上限。比如内网中通讯时,就可以适当调低重试次数,尽快把错误暴露给应用程序。

b. 服务器

当服务器收到 SYN 报文后,服务器会立刻回复 SYN+ACK报文,既确认了客户端的序列号,也把自己的序列号发给了对方。此时,服务器端出现了新连接,状态是 SYN_RCVD。这个状态下,服务器必须建立一个 SYN 半连接队列(3.2讲过)来维护未完成的握手信息,当这个队列溢出后,服务器将无法再建立新连接(3.3详细说过)。

如果 SYN 半连接队列已满,只能丢弃连接吗?并不是这样,开启 syncookies 功能就可以在不使用 SYN 队列的情况下成功建立连接。syncookies 是这么做的:服务器将序列号经过加密算法生成一个Cookie,放在己方发出的 SYN+ACK 报文中发出,当客户端返回 ACK 报文时(客户端回复的ACK中会带上这个SYN Cookie),取出该值验证,如果合法,就认为连接建立成功

图片来源:https://blog.csdn.net/kking_edc/article/details/109480520

4. 四次挥手

建立一个连接需要三次握手,而终止一个连接要经过四次挥手,这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力(比如服务器将自己的接收端关闭后,仍可以接收来自客户端的发送请求,只不过服务器无法进行回传)。

TCP 连接的断开一共需要发送四个包,因此称为四次挥手。数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,这里假设客户端主动关闭,服务器被动关闭。

1)第一次挥手(主动->被动):客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
即发出连接释放报文段(FIN=1,序号seq=u,u等于前面已经传送过来的数据的最后一个字节的序号加1),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。

TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

2)第二次挥手(被动->主动):服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,并且带上自己的序列号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE_WAIT状态持续的时间。

客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段(在这之前还需要接受服务器发送的最后的数据)。

3)第三次挥手(被动->主动):如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。

4)第四次挥手(主动->被动):客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。
即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL(最长报文段寿命)后,客户端才进入CLOSED状态。

服务器结束TCP连接的时间要比客户端早一些。

四次挥手步骤如下:

图片来源:https://gitcode.csdn.net/66c55ce4a0bc797cf7b649bd.html?dp_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mjg0NzQ0NCwiZXhwIjoxNzI5NzM2OTYyLCJpYXQiOjE3MjkxMzIxNjIsInVzZXJuYW1lIjoibTBfNjMwODYxOTgifQ.IdWGuw8i52y5Bl_ybIBCykU8UlkEILXf5ePPFEIFa3g&spm=1001.2101.3001.6650.1&

4.1 为什么客户端最后还要等待2MSL

MSL是Maximum Segment Lifetime的英文缩写,可译为“最长报文段寿命”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态

总结,需要等待2MSL的原因:

第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器

第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

第三,如果主动方不保留TIME_TAIT状态,而是直接CLOSE,那么此时连接的端口恢复了自由身,可以复用于新连接。然而,被动方的 FIN 报文可能再次到达,这既可能是网络中的路由器重复发送,也有可能是被动方没收到 ACK 时基于 tcp_orphan_retries 参数重发。这样,正常通讯的新连接就可能被重复发送的 FIN 报文误关闭。保留 TIME_WAIT 状态,就可以应付重发的 FIN 报文,当然,其他数据报文也有可能重发,所以 TIME_WAIT 状态还能避免数据错乱。

为什么是2MSL不是1.5MSL或者其他值呢?

TIME_WAIT确保有足够的时间让对端收到了ACK,如果被动关闭的那方没有收到Ack,就会触发被动端重发Fin,一来一去正好2个MSL .

这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。

4.2 为什么建立连接是三次握手,关闭连接确是四次挥手?

1)这是因为 TCP 不允许连接处于半打开状态时就单向传输数据,所以在三次握手建立连接时,服务器会把 ACK 和 SYN 放在一起发给客户端,其中,ACK 用来打开客户端的发送通道,SYN 用来打开服务器的发送通道。这样,原本的四次握手就降为三次握手了。

但是当连接处于半关闭状态时,TCP 是允许单向传输数据的。为便于理解,我们把先关闭连接的一方叫做主动方,后关闭连接的一方叫做被动方。当主动方关闭连接时,被动方仍然可以在不调用 close 函数的状态下,长时间发送数据,此时连接处于半关闭状态。这一特性是 TCP 的双向通道互相独立所致,却也使得关闭连接必须通过四次挥手才能做到。

四次挥手的简单步骤:

  • 在TCP连接中,关闭连接是一个双向的过程,客户端和服务器都需要分别关闭各自的发送通道
  • 当客户端发送FIN请求关闭发送通道时,服务器可能还有数据要发送,因此它会先回复ACK,并在数据发送完毕后再发送FIN
  • 客户端收到服务器的FIN后,再发送最后一个ACK确认,这样才能确保连接彻底关闭

简单来说,三次握手是因为只需要确认双方的发送和接收能力即可,但四次挥手需要双方各自关闭发送通道,这个过程需要双方都能确认所有数据都已传输完毕,并且各自关闭了发送和接收通道。

2)建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。

而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

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

如果连接已经建立,但客户端突然故障,服务器不会立即发现,它会持续等待客户端的数据。但TCP设有一个保活计时器,服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

参考:

TCP三次握手和四次挥手_tcp三次握手和4次挥手-CSDN博客​blog.csdn.net/kking_edc/article/details/109480520​编辑icon-default.png?t=O83Ahttps://link.zhihu.com/?target=https%3A//blog.csdn.net/kking_edc/article/details/109480520

两张动图-彻底明白TCP的三次握手与四次挥手_小书go-GitCode 开源社区​gitcode.csdn.net/66c55ce4a0bc797cf7b649bd.html?dp_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mjg0NzQ0NCwiZXhwIjoxNzI5NzM2OTYyLCJpYXQiOjE3MjkxMzIxNjIsInVzZXJuYW1lIjoibTBfNjMwODYxOTgifQ.IdWGuw8i52y5Bl_ybIBCykU8UlkEILXf5ePPFEIFa3g&spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Eactivity-1-72861891-blog-109480520.235%5Ev43%5Epc_blog_bottom_relevance_base6&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Eactivity-1-72861891-blog-109480520.235%5Ev43%5Epc_blog_bottom_relevance_base6&utm_relevant_index=2​编辑icon-default.png?t=O83Ahttps://link.zhihu.com/?target=https%3A//gitcode.csdn.net/66c55ce4a0bc797cf7b649bd.html%3Fdp_token%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mjg0NzQ0NCwiZXhwIjoxNzI5NzM2OTYyLCJpYXQiOjE3MjkxMzIxNjIsInVzZXJuYW1lIjoibTBfNjMwODYxOTgifQ.IdWGuw8i52y5Bl_ybIBCykU8UlkEILXf5ePPFEIFa3g%26spm%3D1001.2101.3001.6650.1%26utm_medium%3Ddistribute.pc_relevant.none-task-blog-2%257Edefault%257EBlogCommendFromBaidu%257Eactivity-1-72861891-blog-109480520.235%255Ev43%255Epc_blog_bottom_relevance_base6%26depth_1-utm_source%3Ddistribute.pc_relevant.none-task-blog-2%257Edefault%257EBlogCommendFromBaidu%257Eactivity-1-72861891-blog-109480520.235%255Ev43%255Epc_blog_bottom_relevance_base6%26utm_relevant_index%3D2

面试官,不要再问我三次握手和四次挥手​yuanrengu.com/2020/77eef79f.html​编辑icon-default.png?t=O83Ahttps://link.zhihu.com/?target=https%3A//yuanrengu.com/2020/77eef79f.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2217790.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaWeb合集03-Maven

三、Maven Maven是apache旗下的一一个开源项目,是一款用于管理和构建java项目的工具。 作用: 依赖管理:方便快捷的管理项目依赖的资源(jar包), 避免版本冲突问题。统一项目结构:提供标准、统一的项目结构,maven项目。…

map和set的模拟实现

一.内容介绍 1.set采用Key的搜索场景,map采用Key/Value的搜索场景,二者的底层均可以用红黑树实现,为了降低代码的冗余量可以通过对红黑树模板的参数做少许改动达到一棵红黑树的基层实现set和map两个派生类的目的。 一些问题: 1…

uniapp uni.uploadFile errMsg: “uploadFile:fail

uniapp 上传后一直显示加载中 1.检查前后端上传有无问题 2.检查失败信息 await uni.uploadFile({url,filePath,name,formData,header,timeout: 30000000, // 自定义上传超时时间fail: async function(err) {$util.hideAll()// 失败// err 返回 {errMsg: "uploadFile:fai…

【达梦数据库】组态王连接达梦数据库的操作步骤

目录 背景环境版本1、建立ODBC连接配置三级目录 背景 客户咨询组态王如何连接达梦数据库,在查找资料时发现目前网络上没有资料适配达梦数据库 环境版本 Window版本:win11 组态王软件:32位 达梦数据库:32位 1、建立ODBC连接配置…

创客项目秀|基于xiaoESP32C3的桌面嵌入式充电站

今天小编给大家带来的是来自B站的新人UP主“不做点东西就焦虑”的桌面充电站项目,该充电站支持有线和无线两种充电方式,为了尽可能多的为桌面的USB设备统一供电,有线充电接口达到13路,充电站的外观试用铝合金CNC加工,具…

HarmonyOS 开发知识总结

1. HarmonyOS 开发知识总结 1.1. resources->base->media中不可以新建文件夹? 项目图片路径resources->base->media中不可以新建文件夹,图片全平级放里面,查找图片不方便,有没有什么其他的办法解决这个难点&#xff…

软件测试学习笔记丨Pycharm运行与调试

本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/23454 Pycharm作为集成开发环境,除了可以编写脚本,还可以运行和调试自己的代码,下面就为大家介绍一下pycharm运行和调试代码的功能如何使用。 代码运行 编…

银行卡风险画像在风险防控中的作用

现在,网络诈骗涉及到银行卡转账的案例不在少数,在这种背景下,如何有效识别、预防和控制银行卡风险,成为银行业及监管机构面临的问题之一。 银行卡风险画像,简而言之,是基于持卡人交易行为、个人信息、信用记…

高级算法设计与分析 学习笔记14 FFT

​ 本章我们研究多项式乘法。 我们直接乘,时间复杂度是n^2。使用FFT则可以变成nlgn ​编辑 可以看到两个n的多项式,我们直接乘,每种组合都要试一遍,就会要是n^2遍 ​编辑 那么要怎么加速呢? ​编辑 首先多项式可…

用户界面设计:视觉美学与交互逻辑的融合

1、什么是用户界面 用户界面(UI)是人与机器之间沟通的桥梁,同时也是用户体验(UX)的重要组成部分。用户界面设计包括两个核心要素:视觉设计(即产品的外观和感觉)和交互设计&#xff…

鸿蒙网络编程系列21-使用HttpRequest上传任意文件到服务端示例

1. 前述文件上传功能简介 在前述文章鸿蒙网络编程系列11-使用HttpRequest上传文件到服务端示例中,为简化起见,只描述了如何上传文本类型的文件到服务端,对文件的大小也有一定的限制,只能作为鸿蒙API演示使用,在实际开…

postgresql执行计划解读案例

简介 SQL优化中读懂执行计划尤其重要,以下举例说明在执行计划中常见的参数其所代表的含义。 创建测试数据 -- 创建测试表 drop table if exists customers ; drop table if exists orders ; drop table if exists order_items ; drop table if exists products ;…

加速功能安全AI 智能化:HIRAIN FuSa AI Agent发布

随着汽车电子电气(E/E)系统复杂性的增加,以及自动驾驶技术的迅猛发展,功能安全研发面临着日益严峻的挑战,研发成本也随之上升。面对这一挑战,经纬恒润凭借在功能安全领域的深厚积累,利用前沿的人…

页面局部使用vue等框架其它部分用JQuery进行交互

这个需求是原有django在网页需要定制一个人员签到信息。状态有三种,在岗,下班。好吧两种。但是你想 1,1.这是两次、共四个可能,00, 10,01,11.其中00是在家。10是在岗。01是。不签到只签退&#…

vue3使用element-plus手动更改url后is-active和菜单的focus颜色不同步问题

在实习,给了个需求做个新的ui界面,遇到了一个非常烦人的问题 如下,手动修改url时,is-active和focus颜色不同步 虽然可以直接让el-menu-item:focus为白色能解决这个问题,但是我就是想要有颜色哈哈哈,有些执…

一买一卖利润赛苹果,二手平台把阴阳检测玩明白了……

小柴最近看到这样一个案例,一网友在社交媒体上哭诉称,自己在某二手平台上看中了一支二手Apple pencil二代触控笔。 平台给出的检测报告显示,该产品是外观完好、功能完好接近全新的S等级产品,这位网友像捡到了宝一样,立…

不入耳开放式耳机哪个品牌好?这些品牌骨灰级开放式耳机推荐

开放式耳机以其独特的设计,不仅避免了长时间佩戴对耳朵造成的压迫感,还能让用户在享受音乐的同时保持对外界的感知,极大提升了使用安全性和舒适度。特别是对于那些长时间佩戴耳机的用户或是户外运动爱好者来说,开放式耳机无疑是一…

网页复制粘贴助手,Chrome网页复制插件(谷歌浏览器复制插件)

一款解决网页限制复制问题的插件,当你遇到限制复制粘贴和右键的网页是不是很头痛?安装这个插件后,点下插件按钮就能解决了 碰到这种情况 也是非常头疼 chrome拓展-chrome插件-强制复制 当我们浏览网页的时候,看到感兴趣的内容就…

Github 优质项目推荐(第七期)

文章目录 Github优质项目推荐 - 第七期一、【LangGPT】,5.7k stars - 让每个人都成为提示专家二、【awesome-selfhosted】,198k stars - 免费软件网络服务和 Web 应用程序列表三、【public-apis】,315k stars - 免费 API四、【JeecgBoot】&am…

校验台账生成网络事业调查表的方法

校验台账生成网络事业调查表的方法 一、打开教育事业统计调查表学校(机构)信息管理标准化台账“采集信息核查辅助工具二、导入本校台账并校验三、调查表统计导出四、完 一、打开教育事业统计调查表学校(机构)信息管理标准化台账“…