三次握手&&四次挥手

2024-05-09

1. 三次握手&&四次挥手

   TCP是面向连接的协议。传输连接是用来传送TCP报文的,TCP连接传输的三个阶段分别为: 连接建立、数据传送和连接释放。 
     TCP连接的建立采用 客户服务器模式 。主动发起连接建立的应用进程叫做客户,而被动等待连接建立的应用进程叫做服务器。
     TCP建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个TCP报文段,三次握手的过程如下图所示。   
                                           
     (2)  第二次握手 :服务器收到 SYN报文段后,如同意连接,则服务器会为该TCP连接 分配缓存和变量 ,并向客户端返回 确认报文段 ,在确认报文段中同步位 SYN = 1 和 确认位 ACK  = 1,确认号 ack = x + 1,同时也为自己选择一个初始序号 seq = y。这时TCP服务器进程进入 同步收到(SYN-RCVD) 状态。
     (3)  第三次握手 :客户进程在收到服务器进程的确认报文后,客户端为该TCP连接 分配缓存和变量 ,并向服务器端返回一个报文段,这个报文段是对服务器确认报文段进行确认,该报文段中 ACK = 1,确认号 seq = y + 1,而自己序号为 x + 1(即第二次握手服务器确认报文段的确认号)。客户端在发送ACK报文段后进入 已建立连接(ESTABLISHED) 状态,这时TCP连接已经建立。
     当服务器收到客户端的确认后,也进入 ESTABLISHED 状态。
     这样选择序号的目的是为了 防止由于网络路由TCP报文段可能存在延迟抵达与排序混乱的问题,从而而导致某个连接的一方对它作错误的解释 。     下图表示了建立连接使用固定的序号存在的问题:   
                                           
     由于一个TCP连接是被一对端点所表示的,其中包括2个IP地址和2个端口号构成的4元组,因此即便是同一个连接也会出现不同的实例,如果连接由于某个报文段长时间延迟而关闭,然后又以相同的4元组被重新打开,那么可以相信延迟的报文段又会被视为有效据重新进入新连接的数据流中,这就会导致数据乱序问题。
     为了避免上述的问题, 避免连接实例间的序号重叠可以将风险降至最低 。
     如前文所述,一个TCP报文段只有同时具备连接的4元组与当前活动窗口的序列号,才会在通信过程中被对方认为是正确的。然而,这也反应了TCP连接的脆弱性:如果选择合适的序列号、IP地址和端口号,那么任何人都能伪造一个TCP报文段,从而打断TCP的正常连接。所以使用初始化序号的方式(通常随机生成序号)使得序列号变得难猜,或者使用加密来避免利用这种缺点被攻击。
     所以,可以明白在建立TCP连接时,客户端和服务器端初始化序列号,就避免了上述的问题。前面说过,TCP序号占32位,范围是0~2 32  - 1,并且可以重用。
     假如 第一次握手可以携带数据的话,如果有人使用伪TCP报文段恶意攻击服务器,那么每次都在第一次握手中的SYN报文中携带大量的数据,因为它不会理会服务器的发送和接收能力是否正常,不断地给服务器重复发送这样携带大量数据的SYN报文,这会导致服务器需要花费大量的时间和内存来接收这些报文数据,这会将导致服务器连接资源和内存消耗殆尽。
     所以,之所以第一次握手不能携带数据,其中的一个原因就是 避免让服务器受到攻击 。而对于第三次握手,此时客户端已经建立了连接,通过前两次已经知道了服务器的接收正常,并且也知道了服务器的接收能力是多少,所以可以携带数据。
     根据前面描述,在第一次握手,客户端向服务发送建立连接请求,第二次握手,服务器同意建立连接,并向客户端返回一个确认报文,至此客户端已经知道了服务器同意建立连接,为什么客户端还需要对服务器的允许连接报文段进行确认?
     第三个ACK报文段的目的简单来说主要是为了 实现可靠数据传输 。
      三次握手的目的不仅在于让通信双方了解一个连接正在建立,还在于利用数据包的选项来承载特殊的信息,交换初始序列号(Initial Sequence,ISN) 。为了实现可靠传输,TCP协议通信双方,都必须维护一个序列号,以标识发送出去的数据报中,哪些是已经被对方收到的。三次握手的过程是通信双方想要告知序列号起始值,并确认已经收到序列号的必经过程。   
                                           
     如上图,在两次握手过程中,通信双方都随机选择了自己的初始段序号,并且第二次握手的时候客户端收到了自己的确认序号,确认了自己的序列号,而服务器端还没有确认自己的序列号,没有收到确认序号, 如果这时候两次握手下就进行数据传递, 序号没有同步,数据就会乱序。即如果只是两次握手,最多只有客户端的起始序列号能被确认,而服务器断的序列号则得不到确认。
     在三次握手的过程中,服务器为了响应一个受到的SYN报文段,会分配并初始化连接变量和缓存,然后服务器发送一个SYNACK报文段进行响应,并等待客户端的ACK报文段。如果客户不发送ACK来完成该三次握手的第三步,最终(通常在一分多钟之后)服务器将终止该半开连接并回收资源。
     这种TCP连接管理协议的特性就会有这样一个漏洞,攻击者发送大量的TCP SYN报文段,而不完成第三次握手的步骤。随着这种SYN报文段的不断到来,服务器不断为这些半开连接分配资源,从而导致服务器连接资源被消耗殆尽。这种攻击就是 SYN泛供攻击 。
     为了应对这种攻击,现在有一种有效的防御系统,称为 SYN cookie 。SYN cookie的工作方式如下:
     连接释放的四次挥手过程如下图所示:   
                                           
     (2)  第二次挥手 :服务器收到连接释放报文段后即发出确认,确认为ACK = 1,确认号为ack = u + 1,序号seq = v(其值是服务器前面已传送过的数据最后一个字节的序号加1),然后服务器就进入了 关闭等待(CLOSE-WAIT) 状态。
     (3)  第三次挥手 :如果此时服务器没有数据要发送了,此时服务器向客户端发出 连接释放报文段 ,其FIN = 1,假设器序号为seq = w(在半关闭状态下服务器可能又发送了一些数据),服务器必须重复上次以发送的确认号ack = u + 1(因为客户端没有向服务器发送过数据,所以确认号和上次一致)。这时,服务器进入 最后确认(LAST-ACK) 状态,等待客户端的确认。
     (4)  第四次挥手 :客户端在收到服务器端发出的连接释放报文段后,必须对此发出确认,在确认报文段中将ACK置位1,确认号ack = w + 1,而自己的序号为seq = u + 1。之后客户端进入 时间等待(TIME-WAIT) 状态。在经过 时间等待计时器 设置的时间 2MSL 后,客户端才进入 关闭(CLOSE) 状态
     这是为了 保证客户端发送的最后一个ACK报文段能够到达服务器端。 
     客户端发送的ACK报文段可能丢失,因而使服务器收不到对自己已发送的释放连接报文段的确认。服务器会重传连接释放报文段,重新启动2MSL计时器,最终,客户端和服务器端都能进入CLOSE状态。
     在建立连接时,服务器端处于LISTEN状态时,当收到SYN报文段的建立连接请求后,它可以把ACK报文段和SYN报文段(ACK报文段起确认作用,即确认客户端的连接建立请求;SYN报文段起同步作用)放在一起发送,所以在连接建立时四次握手(即第二次握手时,服务器的ACK报文段和SYN报文段分开发送)可以合并为三次握手。
     而在释放连接时需要四次是因为 TCP连接的半关闭造成的 。由于TCP是 全双工 的(即数据可在两个方向上同时传递),因此,每个方向都必须要单独进行关闭,这个单方向的关闭就叫 半关闭 。在关闭连接时,当服务器收到客户端的FIN报文通知时,它仅仅表示客户端没有数据发送服务器了;但服务器未必将所有的数据都全部发送给了客户端,所以服务器端未必马上也要关闭连接,也即服务器端可能还需要发送一些数据给客户端之后,再发送FIN报文给客户端来表示现在可以关闭连接了,所以 它这里的ACK报文和FIN报文多数情况下都是分开发送的 ,这也是为什么释放连接时需要交换四次报文了。

三次握手&&四次挥手

2. 网络--三次握手

 由高到低
   应用层是体系结构中的最高层,直接为用户的应用进程(正在运行的程序)提供服务 。在因特网中的应用层协议很多,如支持万维网应用的 HTTP协议 ,支持文件传输的 FTP协议 ,支持电子邮件的 SMTP协议 等等。
   运输层的任务是负责向 两个主机中进程之间的通信提供服务 。由于一个主机可同时运行多个进程,因此运输层有 复用 和 分用 的功能。 复用就是多个应用层进程可以同时使用下面运输层的服务,分用则是运输层把收到的信息分别交付给上面应用层中的相应的进程 。
   运输层主要使用两种协议:
   网络层负责为分组交换网上的不同 主机 提供通信服务。在发送数据的时候,网络层把运输层产生的报文段或者用户数据报封装成 分组 或 包 进行传送。在 TCP/IP 体系中,由于网络层使用 IP 协议,因此分组也叫 IP数据报 ,或简称 数据报 。
    无论在哪一层传送的数据单元,习惯上都可以笼统地用“分组”来表示    因特网是一个很大的互联网,它由大量的 异构 网络通过 路由器 (router)相连接。因特网主要的网络层协议是无连接的 网际协议IP 和许多种路由选择协议,所以因特网的网络层也叫 网际层 或者 IP层 。
   简称 链路层 。两个主机之间的数据传输总是在一段一段的链路上传送的,也就是说,在两个相邻结点之间(主机和路由器之间或者两个路由器之间)传送数据是直接传送的(点对点)。这时就需要使用专门的链路层的协议。 在两个相邻结点之间传送数据时,数据链路层把网络层交下来的 IP数据报 组装成 帧 (frame),在两个相邻结点间的链路上“ 透明 ”的传送 帧 中的数据。每一帧包括 数据 和必要的 控制信息 (如同步信息、地址信息、差错控制等)。典型的帧长是几百字节到一千多字节。
    透明:某一个实际存在的事物看起来却好像不存在一样 。   在接收数据时, 控制信息 使接收端能够知道一个帧从哪个比特开始和到哪个比特结束,还使接收端能够检测到所收到的帧中有无差错,如发现错误,数据链路层就简单地 丢弃 这个出了差错的帧,以免继续浪费网络资源。如需改错,则交给 运输层的TCP协议 完成。
   在物理层上传输数据的单位是 比特 。物理层的任务就是 透明地传送比特流 。
   在因特网所使用的各种协议中,最重要的和最著名的就是 TCP 和 IP 两个协议。现在人们经常提起的 TCP/IP 并不一定是单指 TCP 和 IP 这两个具体的协议,而是表示因特网所使用的整个 TCP/IP协议族 (Protocol suite)
    TCP 运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。因此,运输连接就有三个阶段: 连接建立、数据传送和连接释放 。运输连接的管理就是使运输连接的建立和释放都能正常地进行。
   在 TCP 建立连接的过程中要解决三个问题:
    TCP 连接的建立采用 客户服务器方式 。主动发起连接建立的应用进程叫做 客户 (Client),被动等待连接建立的应用程序叫做 服务器 (Server)。   假设 主机A 运行的是 TCP客户程序 , 主机B 运行 TCP服务器程序 。最初两端的TCP进程都处在 CLOSED (关闭)状态。    A主动打开连接,而B被动打开连接。     B 的 TCP服务器 进程先创建 传输控制块TCB ,准备接受客户进程的连接请求。然后服务器就处于 LISTEN(收听)状态 ,等待客户的连接请求,如有,即作出反应。
       A 的 TCP客户 进程也是首先创建 传输控制模块TCB ,然后向 B 发出 连接请求报文段 , ——> 首部中的同步位  SYN = 1 ,同时选择一个初始序号  seq = x , ——> TCP客户进入 SYN-SENT (同步以发送)状态。    注 :TCP规定, SYN 报文段(即SYN = 1的报文段)不能携带数据,但要 消耗掉一个序号。 
       B 收到连接请求报文段后,如同意建立连接,则向 A 发送 确认 。 ——> 在确认报文段中把 SYN 位和 ACK 位都 置1 ,确认号是 ack = x+1 ,同时也为自己选择一个初始序号 seq = y 。( 注 :该确认报文段也不能携带数据,但同样要 消耗掉一个序号 。) ——> 这时, TCP服务器进程 进入 SYN-RCVD (同步收到)状态。
       TCP客户 进程收到 B 的确认后,还要向 B 给出确认。 ——> 确认报文段的 ACK置1 ,确认号 ack = y+1 ,而自己的序号 seq = x + 1 ( 注 :TCP规定, ACK报文段 可以携带数据,但 如果不携带数据则不消耗序号 ,在这种情况下,下一个数据报文段的序号仍是 seq = x +1 。) ——> 这时, TCP连接 已经建立, A 进入 ESTABLISHED (已建立连接)状态。      当 B 收到 A 的确认后也进入 ESTABLISHED 状态。
      主要是为了防止已失效的连接请求报文段突然又传送到了 服务器主机B       假定 A 发出连接请求,但因连接请求报文丢失而未收到确认,于是 A 再重传一次连接请求,后来收到了确认,建立了连接,数据传输完毕后就释放了连接。这个过程中, A 共发送了两个请求报文段,其中第一个丢失,第二个到达了 B 。      于是就 可能有“已失效的连接请求报文段产生” :假定一种异常的情况,即 A 发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间的滞留了,以致延误到第二个请求报文段连接释放以后的某个时间才到达 B 。本来这是一个已失效的报文段。但 B 收到此失效的连接请求报文段后,就误以为 A 又一次发出了一次新的连接请求,于是就向 A 发送 确认报文段 ,同意建立连接请求。假如不采用三次握手,那么只要 B 发出确认,新的连接就建立了。      由于现在 A 并没有发出建立连接的请求,所以不会理睬 B 的确认,也不会向 B 发送数据,但是 B 却以为新的运输连接已经建立了,并一直等待 A 发来数据。于是, B 的许多资源就这样被白白浪费了。       采用三次握手,A 不会向 B 的确认发出确认,B由于收不到确认,就知道A并没有要求要建立连接。 

3. HTTP 三次握手,四次挥手(为什么是三次握手四次挥手)

 1.HTTP请求 为什么是三次握手四次挥手?   2.为什么是三次握手不是两次握手?
   TCP 报文格式:
                                           标志位含义:  1.ACK : 确认序号有效          2.SYN:发送一个新的链接            3.FIN:释放一个链接
                                            第一次握手:   客户端什么都不确定。服务端确认对方发送正常。    第二次握手:   客户端发送/接受正常,对方发送接收正常。服务端确认自己发送正常,客户端发送正常。    第三次握手:   客户端发送/接受正常,服务端发送接受正常。服务端确认自己发送/接受正常,客户端发送接受正常。
                                           当网络原因服务端没有收到客户端的请求,且没有给客户端反馈。超时后客户端会再次向服务端发送请求。当网络畅通后服务器段收到最开始的请求并反馈给客户端。导致客户端认为自己未发送这个请求,服务端认为自己发送了一个新的请求,导致服务端性能浪费。

HTTP 三次握手,四次挥手(为什么是三次握手四次挥手)

4. 三次握手四次挥手通俗解释

一、三次握手
目的是确保通信双发具有收发数据的能力
现在假如客户端A向服务端B发送建立连接的请求,如果B收到了,那么对于B来说,就会知道A发送数据的能力是没有问题的,同时也知道自己接受数据的能力是没有问题的。
此时B会给A发送一个响应请求,如果A收到了,那么对于A来说,就会知道B发送数据的能力是没有问题的,同时也会知道B接受数据的能力是没有问题的,因为A知道只有自己发送建立连接的请求被B接受, B才会响应的。
到这为止,我们已经经过两次握手了!!!。总结一下,这个时候A知道B发送和接受数据的能力,B只知道A发送数据的能力。因此我们还需证明A接受数据的能力才行!!!。所以还需要经过第三次握手。
A发送确认建立连接的请求,如果B收到了,那么说明A接受数据的能力是没有问题的,因为B知道,只有A在收到B的响应请求后才会发送确认建立连接的请求。这个时候,双方都证明了对方收发数据的能力是没有问题的。

二、四次挥手
目的是断开连接
举个例子,客户端A(女生)、服务端B(男生)
A:分手(发出取消连接的请求)
B:哦,我知道了(收到了A的请求,这个时候B会在后台处理数据,处理完数据后会再次发送响应信息,询问是否真的要取消)
B:  真的要分手吗(再次发送响应信息)
A:  嗯,拉倒吧!
经过这四次,A和B彻底的分手了,也就是彻底的断开连接了

5. 三次握手,四次挥手(详解)

图示:
                                          
     在TCP/IP协议中,TCP协议提供可靠的连接服务,采取三次握手建立一个连接,
       第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入syn_send状态,等待服务器确认;
       第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即syn+ack包,此时服务器进入syn_recv状态;
       第三次握手;客户端收到服务器的SYN+ACK 包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入established状态,完成三次握手。
       完成三次握手,客户端与服务器开始传送数据
  
 
                                          
 
  
      在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接,完成三次握手,客户端与服务器开始传送数据。由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。且四次挥手可由任何一段发起,这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。TCP四次挥手之后就关闭该连接。

三次握手,四次挥手(详解)

6. 三次握手和四次挥手

 三次握手的流程图:
                                           在网络数据传输中,传输层协议TCP(传输控制协议)是建立连接的可靠传输,TCP建立连接的过程,我们称为三次握手。
    第一次,客户端向服务器发送SYN同步报文段,请求建立连接    客户端发送网络包,服务端收到了。   这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
    第二次,服务器确认收到客户端的连接请求,并向客户端发送SYN同步报文,表示要向客户端建立连接    服务端发包,客户端收到了。   这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
    第三次,客户端收到服务器端的确认请求后,处于建立连接状态,向服务器发送确认报文    客户端发包,服务端收到了。   这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
   因此,需要三次握手才能确认双方的接收与发送能力是否正常。
   无法确认客户端的接收能力。   假设第二次握手的报文丢失了,或者是说有人恶意向服务器不断发送SYN同步报文(SYN洪水)。那么服务器端就会有大量的无效连接,服务器处理连接的数量是有限的,当有大量的无效连接建立后,服务器处理有效连接是能力就会受限,且建立连接会消耗大量是资源,至此有可能导致服务器崩溃。
   因为三次已经足够确认双方的发送和接收的能力了,四次以及四次以上当然就没必要啦
    可以,但是只有第三次,此时的established状态相对安全并且够确认服务器的接收发送能力。但是,第一次、第二次握手不可以携带数据 
   为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
   也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。
   服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。
   当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。
   SYN Flood 属于典型的 DoS/DDoS 攻击。其攻击的原理很简单,就是用客户端在短时间内伪造大量不存在的 IP地址,并向服务端疯狂发送SYN。对于服务端而言,会产生两个危险的后果:
   处理大量的SYN包并返回对应ACK, 势必有大量连接处于SYN_RCVD状态,从而占满整个半连接队列,无法处理正常的请求。   由于是不存在的 IP,服务端长时间收不到客户端的ACK,会导致服务端不断重发数据,直到耗尽服务端的资源。
   增加 SYN 连接,也就是增加半连接队列的容量。   减少 SYN + ACK 重试次数,避免大量的超时重发。   利用 SYN Cookie技术,在服务端接收到SYN后不立即分配连接资源,而是根据这个SYN计算出一个Cookie,连同第二次握手回复给客户端,在客户端回复ACK的时候带上这个Cookie值,服务端验证Cookie 合法之后才分配连接资源。
   下面来看看四次挥手的流程图:
                                           中断连接端可以是客户端,也可以是服务器端。
   不像建立连接的过程,服务器端在调用了accept()之后,剩下的都交给内核来处理,用户空间不用做什么,断开连接是,A端调用close()关闭文件描述符后,A端就停止发送数据了进行发送,B端收到后结束报文段之后,的得知A端要断开连接了,但是B端可能有自己还没有处理完的数据,不能立即断开连接,就要先给出回复,表示自己已经收到消息了,然后将自己的数据处理完之后,可以断开连接的时候,再调用close()发出断开连接请求,在收到A端的确认回复之后,断开连接,一共需要四次挥手。
   MSL是 最长报文段寿命,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。    2MSL等待状态:它是任何报文段被丢弃前在网络内的最长时间。 
   (1)保证客户端发送的最后一个ACK报文段能够到达服务端。
   (2)防止“已失效的连接请求报文段”出现在本连接中。   客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。
    上面是一方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况,    具体流程如下图:
                                           参考资料:    一篇文章带你熟悉 TCP/IP 协议     「计算机网络」前端必备知识,看到就是赚到系列(上)     什么是三次握手、四次挥手     面试官,不要再问我三次握手和四次挥手 

7. 网络--四次挥手

 数据传输结束后,通信的双方都可以释放连接,此时,客户机 A 和服务器 B 都处在 ESTABLLISHED (已建立连接)状态。   ①.     A 的应用进程先向 TCP 发出连接释放报文段,并停止发送数据,主动关闭 TCP 连接。 A 把 连接释放报文段首部的 FIN 置 1,其序号 seq = u,它等于前面已传送过的数据的最后一个字节的序号加  1 。这时, A 进入 FIN-WAIT-1 (终止等待1)状态,等待 服务器B 的确认。   ( 注 : TCP 规定, FIN 报文段即使不携带数据,也会消耗一个序号。)   ②.     B 收到连接释放报文段后即发出确认,确认号为 ack = u+1,而这个报文段自己的序号是 v,等于 B 前面已传送过的数据的最后一个字节的序号加 1 。之后 B 就进入 CLOSE-WAIT (关闭等待)状态。 ——> 这时, TCP服务器进程 应通知 高层应用进程 ,因而从 A 到 B 这个方向的连接就释放了, TCP 连接此时处于 半关闭(half-close) 状态,即 A 已经没有数据要发送了,但 B 若发送数据, A 仍要接收。也就是说,从 B 到 A 这个方向的连接并没有关闭。   ③.     A 收到来自 B 的确认后,进入 FIN-WAIT-2 (终止等待2)状态,等待 B发出的连接释放报文段 。   若 B 已经没有要向 A 发送的数据,其 应用进程 就通知 TCP 释放连接。 ——> 这时, B 发出的连接释放报文段必须使 FIN = 1 ,假定 B 的序号为  w (在半关闭状态 B 可能又发送了一些数据), B 还必须重复上传已发送过的确认号 ack = u+1 。 ——> 这时, B 进入 LAST-ACK (最后确认)状态,等待 A 的确认。   ④.     A 在收到 B 的连接释放报文段后,必须 对此发出确认 。在 确认报文段中把ACK 置 1 ,确认号 ack = w+1,而自己的序号是 seq = u+1 (注:TCP标准,前面发送过的FIN报文段要消耗一个序号) ——> 此时, A 进入 TIME-WAIT (时间等待)状态。 注意,现在  TCP 连接还没有释放掉。必须经过 时间等待计时器(TIME-WAIT timer)设置的时间 2MSL 后,A  才进入CLOSED 状态 。( 注 :时间  MSL  叫做  最长报文段寿命  , RFC 793 建议设置为2分钟,对于如今的网络来说,2分钟太长了,因此TCP允许不同的实现可以根据具体的情况使用更小的 MSL  值。) ——> 所以,从 A 进入 TIME-WAIT 状态后,要经过4分钟才能进入 CLOSED 状态,才能开始建立下一个新的连接。 ——> 当 A 撤销了相应的 传输控制块TCB 后,就结束了这次的 TCP 连接。
    B 只要收到了 A 发出的确认,就进入了 CLOSED 状态,同样, B 在撤销相应的传输控制块TCB后,就结束了这次的 TCP 连接。 B 结束TCP连接的时间比 A 要早一些。 
   理由:   第一,为了保证 A 发送的最后一个  ACK报文段 能过到达 B 。这个 ACK报文段 可能丢失,因而使处在  LAST-ACK 状态下的 B 收不到 对已发送的 FIN+ACK报文段的确认 。 B 会 超时重传 这个 FIN+ACK报文段 ,而 A 就能在  2MSL 时间内收到这个重传的  FIN+ACK 报文段。接着,  A  重传一次确认,重新启动  2MSL计时器 。最后, A  和  B  就能都正常的进入 CLOSED 状态。如果 A 在 TIME-WAIT 状态下不等待一段时间,而是在发送完 ACK 报文段之后立即释放连接,那么无法收到 B 重传的 FIN+ACK ,因而也不会再发送一次 确认报文段 ,那么。 B 就无法按照正常的步骤进入 CLOSED 状态。   第二,为了防止 “已失效的连接请求报文段” 出现。 A 在发送完最后一个 ACK报文段 后,经过时间 2MSL 后,就可以使本连续的时间内所产生的所有报文段(包括旧的连接请求报文段)都从网络上消失。
   服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是 两小时。若两小时没有收到客户的数据,服务器就发送一个 探测报文段 。以后则 每隔75 分钟 发送一次,若一连发送  10个探测报文段 后仍无客户的响应,服务器就会认为客户端除了故障,接着关闭了连接。所以说, 保活计时器就是为了处理在客户端出了故障的时候,让服务器不再白白等下去而浪费资源 。

网络--四次挥手

8. 网络的三次握手是怎么回事?

TCP握手协议

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

SYN:
同步序列编号(Synchronize
Sequence
Numbers)

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据
最新文章
热门文章
推荐阅读