TCP三次握手四次挥手及time_wait状态解析

TCP的建立——三次握手

在这里插入图片描述
1.服务器必须准备好接受外来的连接。通常通过调用socket,bind,listen这三个函数来完成,我们称之为被动打开(passive open)。
2. 客户端通过调用connect函数发起主动的打开(active open)。这导致客户TCP发送一个SYN(同步)分节,它告诉服务器客户将在(待建立的)连接中发送的数据的初始序列号。通常SYN分节不携带任何数据,其所在IP数据报只含有一个IP首部,一个TCP首部以及可能有的TCP选项。
3. 服务器必须确认(ACK)客户的SYN,同时自己也发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器单个分节中发送SYN和客户SYN的ACK(确认)。(客户端的connect函数返回)
4. 客户必须确认服务器发来的SYN,发送一个ACK,然后服务器的accept函数返回。

这种交换至少需要三个分组,因此称之为TCP的三次握手。上图展示了所交换的三个分节。

SYN、ACK的序列号

上图给出的客户初始序列号为J,服务器的初始序列号为K。ACK中的确认号发送这个ACK一端所期待的下一个序列号。因为SYN占据一个字节的序列号空间,所以每一个SYN的ACK确认号就是SYN的初始序列号加1。类似的下文中断开连接的FIN的ACK也是FIN的序列号加1。

当然三次握手最主要的目的是为了知道双方的初始序列号,因为TCP是全双工通信。这样后续的信息的收发才能确保准确安全

TCP断开——四次挥手

在这里插入图片描述

TCP终止一个连接需要四个分节。
1.某个应用进程首先调用close,我们称之为该端执行主动关闭(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。
2.接收到这个FIN的对端执行被动关闭(passive close)。这个FIN由TCP确认(发送ACK进行确认)。它的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程(放在已排队等候应用进程接收的任何其它数据之后),因为FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。
3.一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。
4.接收这个最终FIN的原发送端TCP(即主动关闭的那一端)确认这个FIN(发送ACK进行确认)。

既然每个方向都需要一个FIN和一个ACK,因此通常需要四个分节,所以我们称他为四次挥手。

在步骤2与步骤3之间,执行被动关闭的一端到执行主动关闭一端数据流动是可能的。这称为半关闭

面试经典问题,tcp四次挥手可以变成三次吗?
答案是可以的。我们先抓个包来验证一下:
在这里插入图片描述
大家可以看到,这里我将客户端关闭并抓包进行查看,首先是客户端(port = 44722)给服务端(port = 8848)发送了一个FIN请求关闭,然后服务端将FIN和ack合并成一条发给了客户端,然后客户端在发送ack给服务端,关闭完成。
这里四次挥手->三次挥手就是服务端将FIN和ack合并成一条进行发送。为什么会进行合并呢?是因为在关闭的时候,服务端没有数据发送给客户端,然后优化后就会将FIN和ack合并在一起发送给客户端。


time_wait

1. 首先什么是time_wait

在这里插入图片描述
如上图,在服务器端发送一个FIN时,客户端会处于time_wait状态。当处于time_wait状态时,我们无法创建新的连接,因为端口被占用。

2. time_wait有什么作用

(1)可靠的终止TCP连接。
若处于time_wait的客户端发送给服务器确认报文段丢失的话,服务器将在此重新发送FIN报文段,那么客户端必须处于一个可接收的状态就是time_wait状态而不是close状态。
(2)保证让迟来的TCP报文段有足够的时间识别并丢弃
linux中一个TCP端口不能被打开两次或两次以上,当客户端处于time_wait状态时我们将无法使用此端口建立新连接,如果不存在time_wait状态,新连接可能会收到旧连接的数据。

为什么在time_wait中就可以保证旧数据完全被销毁?

因为网络中数据存在时间最大为MSL(maxinum segment lifetime),而time_wait 持续时间为2MSL所以保证网络中的数据可以丢弃。

3一定是客户端才有time_wait状态吗?

不一定。
 当客户端进行主动关闭时,time_wait存在于客户端,但是当服务器执行主动关闭或者发生异常时,会产生在服务器,所以当服务器异常断开时,你可能需要等待一会才能重启服务器,如果你立即重启服务器,终端会提醒你端口被占用。

在这里插入图片描述
上图是我们启动服务器正常运转,当我的服务器发生异常时,time_wait就存在于服务器,然后我立即重启服务器,则bind函数会返回,如下图所示,端口被占用。
在这里插入图片描述

如何避免time_wait状态占用资源

如果是客户端,我们一般不需要担心,因为客户端一般选择的都是临时端口,再次创建新的连接会分配未被占用的端口。除非客户端指定使用某一个端口,但是不需要这么做。
如果在服务器主动关闭后异常终止,因为服务器使用的是指定的服务器端口,所以time_wait状态将导致它不能重启,需要等待一段时间,但在大型服务器中,会造成巨额的损失。
如何避免这种情况的发生呢? 
1.我们可以使用socket的选项SO_REUSEADDR来强制进程立即使用time_wait状态的连接占用端口。通过setsockopt设置后,即使服务器处于time_wait状态,与之绑定的socket地址也可以立即被重启使用。

setsockopt的用法
在这里插入图片描述
当我在我的服务器中设置好之后,我异常关闭服务器再立即重启就不会显示端口被占用,而是立即可以重启。

2、设置SO_LINGER套接字选项也可以避免TCP的time_wait状态。

#include<sys/socket.h>
struct linger
{
	int l_onoff;
	int l_linger;
};

如果将l_onoff设置为非0值,而l_linger为0。那么当close某个连接时,TCP将中止该连接。这就是说TCP将丢弃保留在套接字发送缓冲区的任何数据,并发送RST给一个对端,而没有通常的四次挥手连接终止序列。这么一来就避免了TIME_WAIT状态。
但是会存在一个问题,在2MSL秒内我们创建该连接的一个化身,导致来自刚被终止的连接上的旧的重复分节被不正确地递送到新的化身上。
下面我们用实际例子进行讲解

我们在服务器端给监听套接字listenfd设置了SO_LINGER选项
    //设置SO_LINGER选项
    struct linger ser_lin;
    ser_lin.l_onoff = 1;
    ser_lin.l_linger = 0;
    setsockopt(listenfd, SOL_SOCKET, SO_LINGER, &ser_lin, sizeof(ser_lin));

然后我们用客户端进行连接,并断开,我用tcpdump抓到如下的包

可以看到当客户端(port = 39624)给服务端(port = 6666)发送了一个FIN分节,告知服务器。因为服务端设置了如上的SO_LINGER选项,导致服务端给客户端发送了RST分节,当客户收到这个分节后就立即断开。因为没有了正常的四次挥手断开连接,所以避免了TIME_WAIT状态。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nginx基础教程

Nginx 目标 Nginx简介【了解】 Nginx安装配置【掌握】 一、Nginx简介 Nginx称为:负载均衡器或 静态资源服务器:html,css,js,img ​ Nginx(发音为“engine X”)是俄罗斯人编写的十分轻量级的HTTP服务器,是一个高性能的HTTP和反向代理服务器&#xff0c;同时也是一个IMAP/P…

初探MyBatis实现简单查询

文章目录一、创建数据库与表1、创建数据库2、创建用户表3、添加表记录二、基于配置文件方式使用MyBatis1、创建Maven项目2、添加相关依赖3、创建用户实体类4、创建用户映射器配置文件5、创建MyBatis配置文件6、创建日志属性文件7、测试用户操作1)创建用户操作测试类2)测试按编号…

除了Jira、禅道还有哪些更好的敏捷开发过程管理平台?

无论是从国内的敏捷调研开发调研报告还是从国外的敏捷状态调查&#xff0c;工具支持一直是决定敏捷成功的关键因素之一&#xff0c;它们可以帮助团队提高软件开发的效率、质量、协作和满意度。选择合适的敏捷开发管理工具&#xff0c;并正确地使用它们&#xff0c;是每个敏捷团…

数字孪生(1)

目前接触的客户群体是做大屏展示&#xff0c;闲鱼上5元包邮的那种科技感前端&#xff08;不好意思我买了&#xff09;各路模型大整合 实景GISiOT&#xff0c;如果再来点动画就好&#xff0c;然满屏动起来&#xff0c;火灾烧起来&#xff0c;水面荡漾起来&#xff0c;工程车开起…

C/C++每日一练(20230414)

目录 1. 寻找峰值 &#x1f31f;&#x1f31f; 2. 相同的树 &#x1f31f; 3. 整数反转 ※ &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 寻找峰值 峰值元素是指其值严格大于左右…

如何借助ChatGPT,自动批量产出短视频爆款文案

如何借助chatgpt批量出爆款文案。 这里我们首先得认识并了解到爆款文案的逻辑。 共通性是打动人&#xff0c;去原创的话&#xff0c;文案能否火&#xff0c;纯靠天吃饭。 所以我们让chatgpt去自己写原创短视频文案&#xff0c;那么chatgpt大概率自由发挥&#xff0c;我们也不…

国产化ChatGPT来袭,景联文科技提供专业数据采集标注服务,人手一个专属ChatGPT或成为可能

ChatGPT作为一个颠覆性的创新&#xff0c;现已成为火爆全球的智能应用。 自ChatGPT爆火以来&#xff0c;国内科技圈开始频频发力&#xff0c;多家科技和互联网公司纷纷表示将开发出中国本土化的ChatGPT。 以百度为例&#xff0c;3月16日&#xff0c;百度推出新一代知识增强大语…

【Linux】页表的深入分析

上一篇文章介绍了线程的基本概念 而本篇文章我们来深入理解一下, CPU再调度我们以往理解的进程和如今的线程都会涉及到的一个内容: 页表 文章目录深入理解页表 *页表的实际组成*什么是page&#xff1f;深入理解页表 * 在介绍进程时, 博主没有深入介绍过页表. 只是简单说了 页…

展心展力 metaapp:基于 DeepRec 的稀疏模型训练实践

作者 metaapp-推荐广告研发部&#xff1a;臧若舟&#xff0c;朱越&#xff0c;司灵通 1 背景 推荐场景大模型在国内的使用很早&#xff0c;早在 10 年前甚至更早&#xff0c;百度已经用上了自研的大规模分布式的 parameter server 系统结合上游自研的 worker 来实现 TB 级别…

“三箭齐发”,诸葛智能三大产品全新升级,助力企业迈向数字化经营 | 爱分析调研

调研&#xff1a;文鸿伟 撰写&#xff1a;文鸿伟 诸葛智能&#xff0c;是容联云旗下敏捷开放的场景化数据智能服务商&#xff0c;累积服务全国1000企业&#xff0c;覆盖泛互联网、泛电商、金融、汽车、产业科技、企服等数十个垂直领域。 自2015年成立至今&#xff0c;诸葛智…

数据库管理-第六十五期 Oracle 23c新特性(20230411)

数据库管理 2023-04-11第六十五期 Oracle 23c新特性1 免费版23c目录结构2 新特性总结第六十五期 Oracle 23c新特性 上一期装了免费版23c&#xff0c;这一期根据安装的数据库&#xff0c;对Oracle 23c的部分新特性进行实验展示。 1 免费版23c目录结构 通过RPM包安装的免费版2…

背包问题-动态规划

背包问题 容量有限的背包&#xff0c;给很多商品&#xff0c;商品有相应的体积与价值 01背包问题 一个背包 每个物品只有一个 最终状态方程 dp[i][j]max(dp[i-1][j],dp[i-1][j-w[i]]v[i]) 推导过程 由上一层推导过来 选择拿不拿i 最终代码 #include<iostream> #…

前段时间面了10多个人,发现这些测试人都有个通病......

前段时间面了15个人&#xff0c;怎么说呢&#xff0c;基本上没有符合要求的&#xff0c;其实一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在10-20k&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。 看简历很多都是3年工作经验&am…

GitHub标星15w,如何用Python实现所有算法?

学会了 Python 基础知识&#xff0c;想进阶一下&#xff0c;那就来点算法吧&#xff01;毕竟编程语言只是工具&#xff0c;结构算法才是灵魂。 新手如何入门 Python 算法&#xff1f; 几位印度小哥在 GitHub 上建了一个各种 Python 算法的新手入门大全。从原理到代码&#xf…

数据 数据元素 数据项 数据对象

文章目录数据、数据元素、数据项和数据对象数据数据元素数据对象数据元素和数据对象数据结构数据结构包括以下三个方面的内容逻辑结构物理结构&#xff08;存储结构&#xff09;逻辑结构与存储结构的关系逻辑结构的种类集合结构线性结构树型结构图状结构或网状结构四种基本的存…

webgl-根据鼠标点击而移动

html <!DOCTYPE html> <head> <style> *{ margin: 0px; padding: 0px; } </style> </head> <body> <canvas id webgl> 您的浏览器不支持HTML5,请更换浏览器 </canvas> <script src"./main.js"></script&g…

【NAS群晖drive异地访问】远程连接drive挂载电脑硬盘「内网穿透」

文章目录前言1.群晖Synology Drive套件的安装1.1 安装Synology Drive套件1.2 设置Synology Drive套件1.3 局域网内电脑测试和使用2.使用cpolar远程访问内网Synology Drive2.1 Cpolar云端设置2.2 Cpolar本地设置2.3 测试和使用3. 结语转发自CSDN远程穿透的文章&#xff1a;【群晖…

[C语言]string.h常用字符串库函数详解+模拟实现

目录 字符串函数 strlen strcpy strcat strcmp strstr 内存函数 memcpy memmove 人生百态&#xff0c;苦事之多。烦恼穿心&#xff0c;何来解脱&#xff1f;打开博客&#xff0c;吸取干货。 以码消愁&#xff0c;以串解忧。泱泱年轮&#xff0c;唯有生活。一起撸串&a…

〖Python网络爬虫实战⑩〗- 正则表达式实战(一)

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付费…

2023 年男生还推荐报计算机专业吗?

计算机专业确实是一个非常热门的专业&#xff0c;就业前景也很广阔。 但是&#xff0c;近些年随着各个大学对计算机专业及其相关专业疯狂扩招&#xff0c;而且每年的毕业人口都在增多&#xff0c;行业是根本容纳不下的&#xff0c;就业竞争力度也急剧上升。因此&#xff0c;选…