当前位置: 首页 > news >正文

TCP如何关闭连接(详细版)

关闭连接的⽅式通常有两种,分别是 RST 报⽂关闭和 FIN 报⽂关闭。
如果进程异常退出了,内核就会发送 RST 报⽂来关闭,它可以不⾛四次挥⼿流程,是⼀个暴⼒关闭连接的⽅式。
安全关闭连接的⽅式必须通过四次挥⼿,它由进程调⽤ close shutdown 函数发起 FIN 报⽂( shutdown 参数须传⼊ SHUT_WR 或者 SHUT_RDWR 才会发送 FIN )。
1 close shutdown 有什么区别
调⽤了 close 函数意味着完全断开连接,完全断开不仅指⽆法接收数据,⽽且也不能发送数据。
此时,调⽤了 close 函数的⼀⽅的连接叫做「孤⼉连接」,如果你⽤ netstat -p 命令,会发现连接对应的进程名为空。
使⽤ close 函数关闭连接是不优雅的。于是,就出现了⼀种优雅关闭连接的 shutdown 函数,它可以控制只关闭 ⼀个⽅向的连接
其中第⼆个参数决定断开连接的⽅式,主要有三种:
1 SHUT_RD(0)
关闭连接的「读」这个⽅向 ,如果接收缓冲区有已接收的数据,则将会被丢弃,并且后续再收到新的数据,会对数据进⾏ ACK ,然后悄悄地丢弃。也就是说,对端还是会接收到 ACK ,在这种情况下根本不知道数据已经被丢弃了。
2 SHUT_WR(1)
关闭连接的「写」这个⽅向 ,这就是常被称为「半关闭」的连接。如果发送缓冲区还有未发送的数据,将被⽴即发送出去,并发送⼀个 FIN 报⽂给对端。
3 SHUT_RDWR(2)
相当于 SHUT_RD SHUT_WR 操作各⼀次,关闭套接字的读和写两个⽅向。
2 FIN_WAIT1 状态的优化
如果 FIN_WAIT1 状态连接很多,我们就需要考虑降低 tcp_orphan_retries 的值。当重传次数超过
tcp_orphan_retries 时,连接就会直接关闭掉(即:新增的孤⼉连接将不再⾛四次挥⼿,⽽是直接发送 RST 复位报⽂强制关闭)。
注: tcp_max_orphans 参数,定义了「孤⼉连接」的最⼤数量。
3 FIN_WAIT2 状态的优化
当主动⽅收到 ACK 报⽂后,会处于 FIN_WAIT2 状态,就表示主动⽅的发送通道已经关闭,接下来将等待对⽅发送FIN 报⽂,关闭对⽅的发送通道。
这时,如果连接是⽤ shutdown 函数关闭的,主动⽅连接可以⼀直处于 FIN_WAIT2 状态,因为它可能还可以发送 或接收数据。
但对于 close 函数关闭的孤⼉连接,由于⽆法再发送和接收数据,所以这个状态不可以持续太久,⽽tcp_fin_timeout 控制了这个状态下连接的持续时⻓,默认值是 60 秒(与 TIME_WAIT 状态持续的时间是相同的)。 它意味着对于孤⼉连接(调⽤ close 关闭的连接),如果在 60 秒后还没有收到 FIN 报⽂,连接就会直接关 闭。
4 TIME_WAIT 状态的优化
TIME_WAIT 的状态尤其重要,主要是两个原因
1 )防⽌收到历史数据,从⽽导致数据错乱的问题
TIME_WAIT 等待时间过短,被延迟的数据包抵达后会发⽣什么呢?
TIME_WAIT 设计为 2MSL ,⾜以让两个⽅向上的数据包都被丢弃,使得原来连接的数据包在⽹络中都⾃然消失,再出现的数据包⼀定都是新建⽴连接所产⽣的。
注:
MSL 全称是 Maximum Segment Lifetime ,它定义了⼀个报⽂在⽹络中的最⻓⽣存时间(报⽂每经过⼀次路由器的转发,IP 头部的 TTL 字段就会减 1 ,减到 0 时报⽂ 就被丢弃,这就限制了报⽂的最⻓存活时间)。
2 )为什么是 2 MSL 的时⻓呢?
这其实是相当于⾄少允许报⽂丢失⼀次。⽐如,若 ACK 在⼀个 MSL 内丢失,这样被 动⽅ ᯿ 发的 FIN 会在第 2 个 MSL 内到达, TIME_WAIT 状态的连接可以应对。
Linux 系统中, MSL 的值固定为 30 秒。
等待⾜够的时间以确保最后的 ACK 能让被动关闭⽅接收,从⽽帮助其正确关闭
3 )假设 TIME_WAIT 没有等待或等待的时间过短,断开连接会造成什么?
如上图红⾊框框客户端四次挥⼿的最后⼀个 ACK 报⽂如果在⽹络中被丢失了,此时如果客户端 TIMEWAIT 过短或 没有,则就直接进⼊了 CLOSE 状态了,那么服务端则会⼀直处在 LAST-ACK 状态。
当客户端发起建⽴连接的 SYN 请求报⽂后,服务端会发送 RST 报⽂给客户端,连接建⽴的过程就会被终⽌。
注:
Linux 提供了 tcp_max_tw_buckets 参数,当 TIME_WAIT 的连接数量超过该参数时,新关闭的连接就不再经历TIME_WAIT ⽽直接关闭。查看系统的 TIME_WAIT 的连接数量:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 如何进行 AWS 云监控
  • Meta关闭Spark AR平台:未来规划与影响分析
  • 内存分配算法
  • SpringBoot实现前后端传输加密设计
  • Elasticsearch 基本语法使用
  • 排除挖矿木马
  • Node.js 异步编程深度解析:回调函数、Promise 以及 async/await
  • Vue3 使用 富文本编辑器 wangeditor/editor-for-vue 配置详解
  • MySQL之SUBSTRING 和 SUBSTRING_INDEX函数
  • 个人手机发短信和106短信群发平台的本质区别是什么?
  • 【开发实战】QT5 + 深度学习六大应用案例
  • PCL 移动立方体三维重建——RBF算法【2024最新版】
  • 计算机网络-VRRP工作原理
  • 时下改变AI的6大NLP语言模型
  • 【TDesign】如何修改CSS变量
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • Asm.js的简单介绍
  • golang中接口赋值与方法集
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • JavaScript 奇技淫巧
  • JDK9: 集成 Jshell 和 Maven 项目.
  • mysql 数据库四种事务隔离级别
  • MySQL的数据类型
  • Next.js之基础概念(二)
  • oldjun 检测网站的经验
  • Python进阶细节
  • Theano - 导数
  • vue的全局变量和全局拦截请求器
  • 第2章 网络文档
  • 给github项目添加CI badge
  • 讲清楚之javascript作用域
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 温故知新之javascript面向对象
  • 一个项目push到多个远程Git仓库
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #define、const、typedef的差别
  • (175)FPGA门控时钟技术
  • (Git) gitignore基础使用
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (web自动化测试+python)1
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (每日一问)基础知识:堆与栈的区别
  • (新)网络工程师考点串讲与真题详解
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • *** 2003
  • ***原理与防范
  • .net操作Excel出错解决
  • [ JavaScript ] JSON方法
  • [20170713] 无法访问SQL Server
  • [2019红帽杯]Snake