TCP三次握手和四次挥手

这篇具有很好参考价值的文章主要介绍了TCP三次握手和四次挥手。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

TCP三次握手

TCP三次握手和四次挥手
序列号:建立连接时计算机随机生成的随机数作为初始值,通过SYN包传给接收端主机,每发送一次数据就累加一次该数据字节数的大小。用来解决网络包乱序问题
确认应答号:指下一次期望收到的数据的序列号,发送端收到这个确认应答以后认为在这个序号以前的数据都已经被正常接受。用来解决丢包问题
ACK:确认应答的字段变为有效,TCP规定除了最初建立的SYN包外该位必须设置为1
RST:表示TCP连接中出现异常必须强制断开连接
SYN:表示希望建立连接,并在其序列号的字段进行序列号初始值的设定
FIN:表示今后不会再有数据发送,希望断开连接。通信结束希望断开连接时,通信双方的主机之间就可以相互交换FIN位为1的TCP段。

使用TCP前必须先建立连接,建立连接是通过三次握手来进行的。
TCP三次握手和四次挥手
三次握手中,第三次握手是可以携带数据的,前两次握手是不可以携带数据的。一旦完成三次握手,双方都处于ESTABLISHED状态,此时连接就已建立完成,客户端和服务端就可以相互发送数据了。
Linux系统查看TCP状态
netstat -napt
TCP三次握手和四次挥手

TCP四次挥手

TCP三次握手和四次挥手
客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。
客户端收到服务端的 ACK 应答报文后,之后进入 ==FIN_WAIT_2 ==状态。
等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。

为什么挥手需要四次?
关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送(closed_wait),等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,因此是需要四次挥手。
第一次挥手丢失,会发生什么?
根据 tcp_orphan_retries 决定重传次数
TCP三次握手和四次挥手

第二次挥手丢失,会发生什么?
由于ACK不会重传,如果服务端第二次挥手丢失客户端就会触发超时重传机制,重传FIN报文
根据 tcp_orphan_retries 决定重传次数
TCP三次握手和四次挥手
注意:
对于 close 函数关闭的连接,由于无法再发送和接收数据,所以FIN_WAIT2 状态不可以持续太久,而 tcp_fin_timeout 控制了这个状态下连接的持续时长,默认值是 60 秒。
如果主动关闭方使用 shutdown 函数关闭连接,指定了只关闭发送方向,而接收方向并没有关闭,那么意味着主动关闭方还是可以接收数据的,就会死等对方的FIN。
TCP三次握手和四次挥手

第三次挥手丢失,会发生什么?
同理第一次挥手丢失
TCP三次握手和四次挥手

第四次挥手丢失,会发生什么?
在 Linux 系统,TIME_WAIT 状态会持续 2MSL 后才会进入关闭状态。
客户端在收到第三次挥手后,就会进入 TIME_WAIT 状态,开启时长为 2MSL 的定时器,如果途中再次收到第三次挥手(FIN 报文)后,就会重置定时器,当等待 2MSL 时长后,客户端就会断开连接。
TCP三次握手和四次挥手
为什么 TIME_WAIT 等待的时间是 2MSL?
MSL为报文最大生存时间(单位是时间)TTL是经过路由跳数,因此MSL应该大于等于TTL消耗为0的时间确保报文已被自然消亡。

当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间
至少运行报文丢失一次
连续两次丢包概率万分之一,概率太小,忽略它比解决它更有性价比

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

为什么需要TIME_WAIT状态?
主动发起关闭连接的一方才会有TIME_WAIT。
两个原因:

  • 防止历史连接的数据被后面相同四元组的连接错误的接收
  • 保证被关闭连接的一方,能被正确的关闭
    原因一:
    序列号和初始化序列号并不是无限递增的,会发生回绕为初始值的情况,这意味着无法根据序列号来判断新老数据。
    假设TIME_WAIT没有等待时间或时间过短,被延迟的数据包抵达后会发生什么?
    TCP三次握手和四次挥手
    相当于重新打开新连接,前面被延迟的SEQ=301抵达客户端,而且这个报文的序列号刚好在客户端接收窗口内,因此客户端会正常接收这个数据报文,但这个数据报文是上一个连接残留下来的,这样就产生数据错乱等严重的问题。
    因此为了防止历史连接中的数据被后面相同四元组的连接错误的接收,TCO设计了TIME_WAIT状态,状态会持续2MSL时长,这个时间足以让两个方向上的数据包都被丢弃,使得原来连接的数据包在网络中自然消失,再出现的数据包一定都是新建立连接所产生的

原因二:
等待足够的时间来确保最后的ACK能让被动关闭方接收,从而帮助其正常关闭。

TCP三次握手和四次挥手
服务端收到这个 RST 并将其解释为一个错误(Connection reset by peer),这对于一个可靠的协议来说不是一个优雅的终止方式。
为防止这种情况,客户端等足够长时间确保服务端能够收到ACK,如果服务端没有收到ACK就会触发TCP重传机制,服务端会重新发生一个FIN,这样一去一来刚好两个MSL时间。
客户端在收到服务端重传的 FIN 报文时,TIME_WAIT 状态的等待时间,会重置回 2MSL。
TCP三次握手和四次挥手
TIME_WAIT 过多有什么危害?
占用系统资源,占用端口资源。
注意一个四元组唯一确定一个TCP连接。
服务器出现大量的TIME_WAIT状态原因有哪些?
如果服务器出现大量的 TIME_WAIT 状态的 TCP 连接,就是说明服务器主动断开了很多 TCP 连接。
服务端主动断开连接的场景:

  • HTTP没有使用长连接
  • HTTP长连接超时
  • HTTP长连接请求数量达到上限

场景一:根据大多数 Web 服务的实现,不管哪一方禁用了 HTTP Keep-Alive,都是由服务端主动关闭连接,那么此时服务端上就会出现 TIME_WAIT 状态的连接。
当服务端出现大量的 TIME_WAIT 状态连接的时候,可以排查下是否客户端和服务端都开启了 HTTP Keep-Alive,因为任意一方没有开启 HTTP Keep-Alive,都会导致服务端在处理完一个 HTTP 请求后,就主动关闭连接,此时服务端上就会出现大量的 TIME_WAIT 状态的连接。
场景二:为了避免资源浪费的情况,web 服务软件一般都会提供一个参数,用来指定 HTTP 长连接的超时时间,比如 nginx 提供的 keepalive_timeout 参数。假设设置了 HTTP 长连接的超时时间是 60 秒,nginx 就会启动一个「定时器」,如果客户端在完后一个 HTTP 请求后,在 60 秒内都没有再发起新的请求,定时器的时间一到,nginx 就会触发回调函数来关闭该连接,那么此时服务端上就会出现 TIME_WAIT 状态的连接。
TCP三次握手和四次挥手
如果现象是有大量的客户端建立完 TCP 连接后,很长一段时间没有发送数据,那么大概率就是因为 HTTP 长连接超时,导致服务端主动关闭连接,产生大量处于 TIME_WAIT 状态的连接。可以往网络问题的方向排查,比如是否是因为网络问题,导致客户端发送的数据一直没有被服务端接收到,以至于 HTTP 长连接超时
场景三:
nginx 的 keepalive_requests 这个参数,这个参数是指一个 HTTP 长连接建立之后,nginx 就会为这个连接设置一个计数器,记录这个 HTTP 长连接上已经接收并处理的客户端请求的数量如果达到这个参数设置的最大值时,则 nginx 会主动关闭这个长连接,那么此时服务端上就会出现 TIME_WAIT 状态的连接。
对于一些 QPS 比较高的场景,比如超过 10000 QPS,甚至达到 30000 , 50000 甚至更高,如果 keepalive_requests 参数值是 100,这时候就 nginx 就会很频繁地关闭连接,那么此时服务端上就会出大量的 TIME_WAIT 状态。针对这个场景下,解决的方式也很简单,调大 nginx 的 keepalive_requests 参数就行

服务器出现大量 CLOSE_WAIT 状态的原因有哪些?
CLOSE_WAIT 状态是「被动关闭方」才会有的状态,而且如果「被动关闭方」没有调用 close 函数关闭连接,那么就无法发出 FIN 报文,从而无法使得 CLOSE_WAIT 状态的连接转变为 LAST_ACK 状态。所以,当服务端出现大量 CLOSE_WAIT 状态的连接的时候,说明服务端的程序没有调用 close 函数关闭连接
如果已经建立了连接,但是客户端突然出现故障了怎么办?
客户端出现故障指的是客户端的主机发生了宕机,或者断电的场景。发生这种情况的时候,如果服务端一直不会发送数据给客户端,那么服务端是永远无法感知到客户端宕机这个事件的,也就是服务端的 TCP 连接将一直处于ESTABLISH状态,占用着系统资源。
TCP有一个保活机制:
定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。
如果已经建立了连接,但是服务端的进程崩溃会发生什么?
TCP连接信息由内核维护,当服务端的进程崩溃后,内核需要回收进程所有TCP连接资源,于是内核会发送第一次挥手FIN报文,后续的挥手过程也都是内核完成,无需进程参与,因此即使服务端进程退出,还是能与客户端完成TCP四次挥手操作。文章来源地址https://www.toymoban.com/news/detail-410296.html

到了这里,关于TCP三次握手和四次挥手的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • tcp 三次握手和四次挥手报文分析

     报文抓取如下: 三段报文分析: 第一次:26-96报文交互 Seq-num = 567391014, ACK_NUM = 0; flags = SYN 第二次:96-26报文交互 Seq-num = 416352681,  ACK_NUM = Seq-num + 1 =567391014 +1 =567391015, flags = ACK + SYN,   第三次:26-96报文交互 Seq-num= ACK_NUM= 567391015, ACK_NUM = seq-num +1= 416352681+ 1 = 416352682, flags

    2024年02月04日
    浏览(39)
  • TCP的三次握手和四次挥手······详解

    三次握手是 建立连接 的过程 如图大致为三次握手的流程图: 当客户端对服务端发起连接时,会 先发一个包 连接请求数据,去询问能否建立连接,该数据包称为 “SYN”包 然后,如果对方同意连接,那么对方将会回复一个 “SYN+ACK”包 客户端收到后,回复一个 “ACK”包 ,连

    2024年02月09日
    浏览(25)
  • TCP协议的三次握手和四次挥手

    完整的TCP内容,请参考RFC 9293 TCP协议为应用提供可靠的、有序的的字节流服务。TCP是面向连接的,提供了全双工的通信。TCP使用端口号来识别应用程序服务并在主机之间复用不同的流。 TCP header也像IP header一样,在header中提供了一些专门用于TCP的信息,TCP header之后就是用户数

    2024年02月06日
    浏览(30)
  • 面试题之TCP的三次握手和四次挥手

    TCP的三次握手: 一定由 客户端主动发起 的,发生在建立连接的过程中。 此过程发生在 客户端的connect()函数 和 服务器的accept()函数 之间。 第一次握手: 客户端向服务器发送一个 带有SYN标志的数据包 ,表示客户端请求建立连接。 并且客户端会 选择一个随机的序列号a 放在

    2024年02月07日
    浏览(33)
  • TCP的连接和建立(三次握手和四次挥手)

    ​ 1.TCP连接的建立 ​ 连接的建立,通常称为三次握手。 ​ ​ 建立连接前服务器处在收听状态。 ​ 第一步:客户机的TCP向服务器的TCP发送连接请求报文段。同步位 = 1。这时客户进程进入同步已发送状态。 ​ 第二步:服务器TCP收到连接请求报文段后,如同意建立连接,向客

    2024年02月16日
    浏览(28)
  • 详解TCP/IP的三次握手和四次挥手

    本文章讲解TCP/IP协议的三次握手和四次挥手的流程。 三次握手:为了对每次发送的数据量进行跟踪与协商,确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系,并建立虚连接。 TCP协议位于传输层,作用是提供可靠的字节流服务

    2024年02月09日
    浏览(30)
  • 【新星计划-2023】TCP三次握手和四次挥手讲解

    关于TCP三次握手和四次挥手,各位想必在读大学的时候或者是在面试的时候一定遇到过,三次握手和四次挥手本身是不是太难的,但它容易忘😞,今天我就在这里给大家讲解一下三次握手与四次挥手。 TCP三次握手建立连接, 是TCP数据传输的必要过程 。流程大致分为以下几步

    2024年02月05日
    浏览(31)
  • tcp的三次握手和四次挥手及相关面试题

    TCP的三次握手和四次挥手是计算机网络领域中非常经典的话题,通常在面试中也会被频繁提及。下面是一些可能会被问到的相关问题: 三次握手(Three-Way Handshake) 请解释TCP的三次握手过程。 为什么TCP需要进行三次握手而不是两次或四次? 三次握手中各个阶段的作用是什么

    2024年04月17日
    浏览(25)
  • 【计算机网络】TCP 的三次握手和四次挥手

    TCP 是面向连接的,面向连接就是数据通讯的时候需要进行三次握手,断开通讯的时候需要进行四次挥手。 1.seq(sequence number),序列号,随机生成的 2.ack(acknowledgement number),确认号,ack=seq+1 3.ACK(acknowledgement),确定序列号有效 4.SYN(synchronous),发起新连接 5.FIN(FINISH),完成 TCP三次

    2024年02月10日
    浏览(31)
  • 说说TCP为什么需要三次握手和四次挥手?

    三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包 主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备 过程如下: 第一次握手:客户端给服务端发一个 SYN 报文,并指明

    2024年04月08日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包