计算机网络——三次握手与四次挥手原理

摘要

在互联网使用的各种协中最重要和最著名的就是 TCP/IP两个协议。现在人们经常提到的TCP/IP并不一定单指TCP和IP这两个具体的协议,而往往表示互联网所使用的整个TCP/IP协议族。本博文将详细讲述有关于TCP/IP协议相关的原理。同时将详细介绍三次握手和四次挥手的原理,同时分析面试中的常见问题,帮助大家更好的理解TCP/IP的三次握手四次挥手原理。

计算机网络知识脑图

计算机网络——计算机网络知识脑图_庄小焱的博客-CSDN博客_计算机网络面试题总结

计算机网络大厂面试问题集合

计算机网络——大厂面试问题集合_庄小焱的博客-CSDN博客

计算机网络基础知识

计算机网络——网络基础知识_庄小焱的博客-CSDN博客_数据转发服务器

IP相关基础原理

计算机网络——IP协议基础原理_庄小焱的博客-CSDN博客_ip网络技术

HTTP协议原理

计算机网络——HTTP协议原理_庄小焱的博客-CSDN博客_http协议原理

HTTP的优化方式

计算机网络——HTTP的优化方式_庄小焱的博客-CSDN博客

HTTPS协议原理

计算机网络——HTTPS协议原理_庄小焱的博客-CSDN博客_https协议原理

HTTPS的优化方式

计算机网络——HTTPS的优化方式_庄小焱的博客-CSDN博客

TCP可靠性传输原理

计算机网络——TCP可靠性传输原理_庄小焱的博客-CSDN博客_tcp的可靠性是如何实现的

TCP/IP三次握手四次挥手原理

计算机网络——HTTP的三次握手与四次挥手原理_庄小焱的博客-CSDN博客_三次握手和四次挥手原理

TCP的优化方式

计算机网络——TCP的优化方式_庄小焱的博客-CSDN博客_tcp协议优化技术

DNS协议(域名解析)原理

计算机网络——DNS协议(域名解析)原理_庄小焱的博客-CSDN博客_计算机网络dns

ARP协议(地址解析)原理

计算机网络——ARP协议(地址解析)原理_庄小焱的博客-CSDN博客_地址解析协议的工作原理

ARQ协议(自动重传请求)原理

计算机网络——ARQ协议(自动重传请求)原理_庄小焱的博客-CSDN博客_连续arq协议的原理

DHCP协议原理

计算机网络——DHCP(动态获取IP)原理_庄小焱的博客-CSDN博客_计算机网络dhcp

NAT协议原理

计算机网络——NAT协议(网络地址转换)原理_庄小焱的博客-CSDN博客

ICMP/IGMP协议原理

计算机网络——ICMP/IGMP协议原理_庄小焱的博客-CSDN博客_计算机网络igmp

HTTP网络访问全流程

计算机网络——HTTP网络访问全流程_庄小焱的博客-CSDN博客_网络访问流程

虚拟网路模型原理

计算机网络——虚拟网路模型原理_庄小焱的博客-CSDN博客

其他网络知识

计算机网络——select/poll/epoll底层原理_庄小焱的博客-CSDN博客

计算机网络——cookie/session/token原理_庄小焱的博客-CSDN博客

计算机网络——网络通信加密原理_庄小焱的博客-CSDN博客_网络通信加密

计算机网络——GRPC通信原理_庄小焱的博客-CSDN博客_grpc原理

计算机网络——tcpdump/Wireshark抓包实战_庄小焱的博客-CSDN博客_网络抓包

计算机网络——TCP抓包连接实战_庄小焱的博客-CSDN博客_tcp全连接和半连接

一、HTTP的三次握手原理

三次握手流程:

  1. 第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
  2. 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  3. 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

为什么是三次握手?不是两次、四次?

三次握手才可以阻止重复历史连接的初始化(主要原因)

网络环境是错综复杂的,往往并不是如我们期望的⼀样,先发送的数据包,就先到达⽬标主机,可能会由于⽹络拥堵等乱七⼋糟的原因,会使得旧的数据包,先到达⽬标主机,那么这种情况下 TCP 三次握⼿是如何避免的呢?

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

  • ⼀个旧 SYN 报文比最新的 SYN 报⽂早到达了服务端;
  • 那么此时服务端就会回⼀个 SYN + ACK 报⽂给客户端;
  • 客户端收到后可以根据⾃身的上下⽂,判断这是⼀个历史连接(序列号过期或超时),那么客户端就会发送 RST 报⽂给服务端,表示中止这⼀次连接。
  • 如果是两次握⼿连接,就不能判断当前连接是否是历史连接,三次握⼿则可以在客户端(发送⽅)准备发送第三次报⽂时,客户端因有⾜够的上下⽂来判断当前连接是否是历史连接:
  • 如果是历史连接(序列号过期或超时),则第三次握⼿发送的报⽂是 RST 报⽂,以此中⽌历史连接;
  • 如果不是历史连接,则第三次发送的报⽂是 ACK 报⽂,通信双⽅就会成功建⽴连接; 所以,TCP 使⽤三次握⼿建⽴连接的最主要原因是防⽌历史连接初始化了连接。

三次握手才可以同步双方的初始序列号

TCP 协议的通信双⽅, 都必须维护⼀个序列号, 序列号是可靠传输的⼀个关键因素,它的作⽤:

  • 接收⽅可以去除重复的数据;
  • 接收⽅可以根据数据包的序列号按序接收;
  • 可以标识发送出去的数据包中, 哪些是已经被对⽅收到的

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

四次握⼿其实也能够可靠的同步双⽅的初始化序号,但由于第⼆步和第三步可以优化成⼀步,所以就成了三次握 ⼿。 ⽽两次握⼿只保证了⼀⽅的初始序列号能被对⽅成功接收,没办法保证双⽅的初始序列号都能被确认接收。

三次握手才可以避免资源浪费

如果只有两次握⼿,当客户端的 SYN 请求连接在⽹络中阻塞,客户端没有接收到 ACK 报⽂,就会重新发送SYN ,由于没有第三次握⼿,服务器不清楚客户端是否收到了⾃⼰发送的建⽴连接的 ACK 确认信号,所以每收到⼀个 SYN就只能先主动建⽴⼀个连接,这会造成什么情况呢? 如果客户端的 SYN 阻塞了,重复发送多次 SYN 报⽂,那么服务器在收到请求后就会建⽴多个冗余的无效的连接,造成不必要的资源浪费。

二、HTTP的四次挥手原理

 四次挥手的流程:

  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连接的时间要比客户端早一些。

为什么需要四次挥手?

  • 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
  • 服务器收到客户端的 FIN 报⽂时,先回⼀个 ACK 应答报⽂,⽽服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报⽂给客户端来表示同意现在关闭连接。 从上⾯过程可知,
  • TCP 是全双工模式,并且支持半关闭特性,提供了连接的一端在结束发送后还能接收来自另一端数据的能力。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。
  • 通俗的来说,两次握手就可以释放一端到另一端的 TCP 连接,完全释放连接一共需要四次握手。

为什么 TIME_WAIT 等待的时间是 2MSL?

  1. MSL是Maximum Segment Lifetime,报⽂最⼤⽣存时间,它是任何报⽂在网络上存在的最⻓时间,超过这个时间报⽂将被丢弃。因为 TCP 报⽂基于是 IP 协议的。
  2. TTL 字段: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 时间将重新计时。

在Linux 系统⾥ 2MSL 默认是 60 秒,那么⼀个 MSL 也就是 30 秒。Linux 系统停留在 TIME_WAIT 的时 间为固定的 60 秒 。 其定义在 Linux 内核代码⾥的名称为 TCP_TIMEWAIT_LEN : define TCP_TIMEWAIT_LEN (60*HZ) ,如果要修改 TIME_WAIT 的时间⻓度,只能修改 Linux 内核代码⾥ TCP_TIMEWAIT_LEN 的值,并重新编译 Linux 内核 。

为什么需要 TIME_WAIT 状态?

主动发起关闭连接的⼀⽅,才会有 TIME-WAIT 状态。 需要 TIME-WAIT 状态,主要是两个原因:

  • 防止具有相同四元组的旧数据包被收到;
  • 保证被动关闭连接的⼀⽅能被正确的关闭,即保证最后的 ACK 能让被动关闭⽅接收,从⽽帮助其正常关闭

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

如上图黄色框服务端在关闭连接之前发送的SEQ = 301 报⽂,被网络延迟。 这时有相同端⼝的TCP连接被复⽤后,被延迟的 SEQ = 301 抵达了客户端,那么客户端是有可能正常接收 这个过期的报⽂,这就会产⽣数据错乱等严重的问题。 所以,TCP 就设计出了这么⼀个机制,经过 2MSL 这个时间,⾜以让两个⽅向上的数据包都被丢弃,使得原来 连接的数据包在⽹络中都⾃然消失,再出现的数据包⼀定都是新建⽴连接所产⽣的。

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

  • 如上图红⾊框框客户端四次挥⼿的最后⼀个 ACK 报⽂如果在⽹络中被丢失了,此时如果客户端 TIME- WAIT 过短或没有,则就直接进⼊了 CLOSED 状态了,那么服务端则会⼀直处在 LASE_ACK 状态。
  • 当客户端发起建⽴连接的 SYN 请求报⽂后,服务端会发送RST报⽂给客户端,连接建⽴的过程就会被终止。

如果 TIME-WAIT 等待⾜够⻓的情况就会遇到两种情况 ?

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

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

TIME_WAIT 过多有什么危害?

如果服务器有处于TIME-WAIT 状态的 TCP,则说明是由服务器⽅主动发起的断开请求。 过多的 TIME-WAIT 状态主要的危害有两种:

  • 第⼀是内存资源占⽤;
  • 第⼆是对端⼝资源的占⽤,⼀个 TCP 连接⾄少消耗⼀个本地端口

如何优化 TIME_WAIT?

  1. 打开 net.ipv4.tcp_tw_reuse 和 net.ipv4.tcp_timestamps 选项;

如下的 Linux 内核参数开启后,则可以复⽤处于 TIME_WAIT 的 socket 为新的连接所⽤。 有⼀点需要注意的是,tcp_tw_reuse 功能只能⽤客户端(连接发起⽅),因为开启了该功能,在调⽤ connect() 函数时,内核会随机找⼀个 time_wait 状态超过 1 秒的连接给新的连接复⽤。

  1. net.ipv4.tcp_max_tw_buckets。

这个值默认为 18000,当系统中处于 TIME_WAIT 的连接⼀旦超过这个值时,系统就会将后⾯的 TIME_WAIT 连接 状态重置 。 这个⽅法过于暴⼒,⽽且治标不治本,带来的问题远⽐解决的问题多,不推荐使⽤

  1. 程序中使⽤ SO_LINGER ,应⽤强制使⽤ RST 关闭

我们可以通过设置 socket 选项,来设置调⽤ close 关闭连接⾏为,我们可以通过设置 socket 选项,来设置调⽤ close 关闭连接⾏为 。

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

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

在 Linux 内核可以有对应的参数可以设置保活时间、保活探测的次数、保活探测的时间间隔,以下都为默认值:
tcp_keepalive_time=7200:
表示保活时间是7200秒(2⼩时),也就2⼩时内如果没有任何连接相关的活动,则会启动保活机制
tcp_keepalive_intvl=75:
表示每次检测间隔75秒;
tcp_keepalive_probes=9:
表示检测9次⽆响应,认为对⽅是不可达的,从⽽中断本次的连接。

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

  • 第⼀种,对端程序是正常⼯作的。当 TCP 保活的探测报⽂发送给对端, 对端会正常响应,这样 TCP 保活时间会被 重置,等待下⼀个 TCP 保活时间的到来。
  • 第⼆种,对端程序崩溃重启。当 TCP 保活的探测报⽂发送给对端后,对端是可以响应的,但由于没有该连接的 有效信息,会产⽣⼀个 RST 报⽂,这样很快就会发现 TCP 连接已经被重置。
  • 第三种,是对端程序崩溃,或对端由于其他原因导致报⽂不可达。当 TCP 保活的探测报⽂发送给对端后,⽯沉⼤ 海,没有响应,连续⼏次,达到保活探测次数后,TCP 会报告该 TCP 连接已经死亡。

博文参考

《小林图解网络》

JavaGuide

回答: HTTP的三次握手原理是为了确保客户端和服务端都可以确认之前的通信状况,并建立可靠的连接。 在三次握手中,客户端先向服务端发送一个连接请求,并带上自己的初始序列号。服务端收到请求后,回复一个确认包,同时带上自己的初始序列号。最后,客户端再回复一个确认包,确保双方都收到了对方的初始序列号。通过这样的握手过程,双方可以确认对方的初始化序号,建立起可靠的连接。 关于为什么不需要四次握手,我们需要明白一点,完全可靠的通信协议是不存在的。即使增加握手次数也不能保证后续的通信完全可靠。 在三次握手后,客户端和服务端已经可以确认之前的通信状况,并收到了确认信息。因此,再增加握手次数是没有必要的。四次握手会增加不必要的开销,并且可能导致资源的浪费。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [计算机网络——HTTP的三次握手四次挥手原理](https://blog.csdn.net/weixin_41605937/article/details/107185199)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [最全面的计算机网络三次握手原理详解](https://blog.csdn.net/weixin_44166447/article/details/123041601)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庄小焱

我将坚持分享更多知识

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值