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

网络原理(3)——TCP协议

目录

一、连接管理

二、三次握手

        1、何为三次握手?

        2、三次握手有何意义?

三、四次挥手

三次握手和四次挥手的相似之处和不同之处

   (1)相似之处

   (2)不同之处

四、TCP的状态

建立连接:

断开连接:

CMD控制平台观察上面介绍的状态

LISTEN和ESTABLISHED

CLOSE_WAIT和TIME_WAIT


一、连接管理

        正常情况下,TCP要经历“三次握手”建立连接,“四次挥手”断开连接。

        TCP是有连接的,我们程序员编写客户端代码时,只要:socket = new Socket(String serverIP, int serverPort)操作系统内核中就会自动和服务器建立连接,如图:

        内核是怎么完成上述建立连接的过程的呢?——三次握手

        而当要断开连接时,内核是怎么进行的呢?——四次挥手


二、三次握手

        1、何为三次握手?

        在建立连接的过程中,客户端一定是主动的一方,第一次交互就是客户端发起的,客户端首先要发送给服务器syn(同步报文段),然后服务器收到 syn 后,服务器就会发送ack(应答报文),然后服务器也要发送 syn 给客户端,客户端在收到 syn 后,就会返回一个 ack 给服务器,这是,三次握手的就完成了,如图:

        上面画的好像是四次交互啊,那为啥称为三次握手呢?原因很简单,因为服务器给客户端发送的两个报文,可以合并成一个也就是ack+syn。为什么呢?想象一下,我们网购的时候,同时买了两份商品,商家是不是就会把这两份商品打包成一件商品,一起邮寄给我们,原因很简单,就是节省成本。网络中也是如此,反正ack和syn都要发到客户端中,那为什么不直接打包成一份呢?何况网络传输是要经过层层封装、分用,多一个次传输,传输成本就会增加好多,也就成了三次握手,如下图:

        除了节约成本外,还有一个原因(也是能合并的前提):ack和syn的触发时机是一样的,所以可以把这两个合并在一起。所以100%会合并

        这里客户端在第一次交互中,虽然已经发送给服务器syn了,但是服务器是否要保存客户端的信息,还得观望观望,等这三次握手结束后,才能保存客户端的信息,确立连接,以及后续的通信。

        这里的第一次交互,服务器收到客户端发来的syn,服务器会有两种情况:一、服务器同意,表示服务器也愿意和客户端建立连接二、务器不同意,这种情况很少出现,一般的原因就是服务器的负载极高,已经处理不过来了,客户端发来的请求处理不过来了,服务器完全无法响应,就没有下文了。

        因为服务器是提供服务的,所以客户端发来的请求就一定会尽可能的处理,返回响应,所以一般都会同意客户端的建立请求

                握手的英译:handshake,是一个形象的比喻,握手只是打招呼,不用商讨具体的细节(业务逻辑,也就是应用程序 / 应用层要完成的事情)。其中这里就是简单的建立个连接而已,没有其他操作,还有三次握手也会有超时重传,三次握手结束后,超时重传也还存在。

syn的介绍:所谓的syn就是一个特殊的TCP数据报

        syn是六个标志位的第五位,全称:synchronize ,表示同步的意思,如图:

        表达的语义:我想和你建立连接。这里的 syn 虽然不带有应用层载荷,但也会带有 IP报头 / 以太网数据帧等等,更会有TCP报头其中TCP报头中就包含了客户端自己的端口,IP报头中就包含了客户端的IP

        2、三次握手有何意义?

(1)投石问路,确认客户端和服务器之间的通信通道是否“通畅”

        比如地铁,地铁每天的第一趟不是载客的,而是先空车跑一趟,确认列车是否能正常运行到目的地,中间是否会有故障;而三次握手也是有类似的功能,通信前先确认通信链路是否是通畅的,有一种投石问路的效果。

(2)三次握手,也是在确定通信双方是否能发送信息和接受信息(接受和发送能力是否正常)

        功能和上面画的图一样,如图:

        第一次交互,客户端先给服务器发送syn建立请求,服务器收到了syn后,就知道客户端的发送能力是没有问题的;第二次交互,服务器发送ack+syn给客户端,当客户端收到后,客户端就知道了,自己的发送能力没有问题,服务器的接受和发送能力没有问题;第三次交互,客户端发送ack给服务器,服务器收到ack,服务器就能知道,自己的发送能力和接受能力都没有问题,还有客户端的接受能力也没有问题。

(3)建立连接的过程也会协商一些参数

        因为网络通信是客户端和服务器两方的事情,所以就要配合,就要协商一些信息,保证其中的有些内容要一样。

        TCP协议中也有很多参数是要客户端和服务器双方进行协商的,这些内容往往体现在 选项中,如图

        其中有一个信息是挺关键的:TCP 的通信序号,如图:

        也是因为网络传输中:后发先至(先发后至)的情况是普遍存在的,所以要引入序号这一概念。为了区分不同连接之间的数据包。

        TCP在通信过程中,序号不是从 0 / 1开始的,而是选择一个比较大的数字,以这个数字开头来计算,即使是同一个客户端和服务器,每次连接,开始的序号都不同,原因:避免“前朝的件,斩本朝的官”。啥意思,如图:

        所以,第二次连接,旧的数据应该丢弃。而旧的数据包也能一眼就看出来,原因就是每次连接(就算是同一客户端和服务器的连接),每次开始的序号也会不同,就很容易区别新旧数据包,把旧的数据包丢弃。

        比如清朝的人,和我们现代人走在一起,想象清朝的人是“大粽子”,是不是一眼就能看出来他“不是人”(doge)。


三、四次挥手

        连接的过程,本质是在于服务器和客户端直接能保存对端的信息,是虚拟的连接,而这些信息是要放在数据结构中的

        断开连接的过程,本质就在于把服务器和客户端里保存的对端的信息,在数据结构上给释放掉,是逻辑上的断开连接,也是虚拟的

        其中四次挥手有点类似现实中的离婚的“和离”(和平分手),因为结婚领证后是具有法律效应的,如果要离婚,就会牵扯到财产纠纷问题,并不是其中的一方想离就立即能离的,一般要确认财产分配问题,双方的观念达成一致,才能离成,这种情况就是“和离”;而四次挥手呢,也并不是客户端和服务器的其中一端的单方面情况,想断开连接就断开连接,而是要遵循一些约定,经过四次挥手的过程后,才能断开连接

        那么四次挥手的过程是咋样的呢?(断开连接并不像建立连接,发送端一定是客户端,断开连接的发起者,可以是服务器,也可以是客户端)大概流程如图:

        这里就涉及到四次交互,其中服务器这边,是不可以把ack和fin进行合并!!一起发送给客户端的,为什么呢,原因就是:服务器这边的ack和fin触发时机是不一样的!服务器接受到对端的fin时,就会立即发送ack给对端,而fin要经历一些程序员写的一些代码,一些逻辑后,才能执行服务器这边的代码: socket.close(),才会给对端发fin。当然也不是绝对的,如果服务器这边的如果断开连接的代码很少,fin和发送ack的触发时机几乎是同一时间,这时候服务器当然也可以把ack+fin合并到一起再发送给对端啦。所以,中间两次可以合并吗?我们称为 :如合

        上面这四次交互,就是四次挥手的过程了。

三次握手和四次挥手的相似之处和不同之处

   (1)相似之处

        传输顺序是相似的,都是各自给对端发生 syn / fin,对端返回ack,然后对端再发送 syn / fin ,   当前端再返回回去ack。

        三次握手交互顺序:syn / ack / syn / ack

        四次挥手交互顺序:fin / ack / fin /ack

   (2)不同之处

        发送方的约定不同,三次握手的发送方(主动方)必须是客户端,四次挥手的发送方双方(主动方)都可以。


四、TCP的状态

        下图是TCP状态转换的汇总:

        这里主要介绍四个常用的状态。

建立连接:

        LISTEN状态:在Linux系统是LISTEN,Windows系统是LISTENING;表示服务器这边已经创建好ServerSocket了,并且已经好绑定IP地址和端口了,随时可以接收客户端发来的请求。

        ESTABLISHED状态:表示三次握手的过程已经结束了,客户端和服务器之间已经建立好连接了。

断开连接:

        CLOSE_WAIT状态:表示被动方的这一端,收到了对端发来的fin后,会进入这个状态。

        TIME_WAIT状态:表示主动方这一端,发送给对端fin后,对端也发送fin给我后,本端会处于这个状态,就是为了给最后一个ack的重传留有一定时间。

CMD控制平台观察上面介绍的状态

首先,启动我们之前写的TCP代码,启动这服务器和客户端。

详细代码在:网络编程套接字(4)——Java套接字(TCP协议)-CSDN博客

其中服务器和客户端的端口和地址,如图:

LISTEN和ESTABLISHED

只启动服务器

        在CMD控制平台输入:netstat -ano | findstr 9090

        第一列是协议,第二列是本地地址,第三列是外部地址,第四列是状态,第五列是 PID。

        其中,这里0.0.0.0是本机所有网络接口的地址,是本网络中的本机,也就是说,表示当前设备上所有可用的IP地址,也称为通配地址而127.0.0.1是回环地址,是为了让本机能够实现自我测试和自我通信。

        方括号是IPV6的地址

        服务器的端口号是9090,也就是服务器的地址,当前状态是LISTENING,表示服务器已经绑定好了IP地址和端口,随时可以和客户端建立连接

        大概流程如下图:

启动服务器和客户端

        在CMD控制平台输入:netstat -ano | findstr 9090

        客户端是第三行,服务器是第二行,其中它们的状态都变成了ESTABLISHED表示服务器和客户端两端已经建立了联系

CLOSE_WAIT和TIME_WAIT

        在Windows操作系统,CLOSE_WAIT和TIME_WAIT是不容易被观察到的,用CMD控制平台看不到这个状态。

        其中,这里TIME_WAIT是为了给最后一个ack重传留有一定的时间。其中,最后一个ack要发送给服务器,客户端和服务器之间,在数据结构中保存的对端信息才能被释放掉,如果最后一个ack丢包了,客户端这边也不知道是啥情况,就可以使用TIME_WAIT状态进行标记,如果ack丢包了,就等一定的时间,给客户端这边重传ack提供保障。

        当然,这里也不是无休止的等,是有一定是时间限制的,最多等2MSL(MSL是一个系统内核的配置项表示服务器和客户端之间消耗最多的时间常见的设置值是2 min),这里如果等了2MSL,还没收到客户端发来的ack,也意味着客户端这边不可能会发ack过来了,再也不会重传了,就直接断开连接吧,丢弃一些在数据结构中的信息

        一般而言,对于服务器出现大量的CLOSE_WAIT状态,原因就是服务器没有正确关闭socket,导致四次挥手没有正确完成,这是应该BUG;只需要加上对应的close即可。

相关文章:

网络原理(3)——TCP协议

目录 一、连接管理 二、三次握手 1、何为三次握手? 2、三次握手有何意义? 三、四次挥手 三次握手和四次挥手的相似之处和不同之处 (1)相似之处 (2)不同之处 四、TCP的状态 建立连接: 断开…...

nginx多级代理配置获取客户端真实ip

流量路径 #mermaid-svg-NX785p8k6RVBngHY {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-NX785p8k6RVBngHY .error-icon{fill:#552222;}#mermaid-svg-NX785p8k6RVBngHY .error-text{fill:#552222;stroke:#552222;}#…...

Django框架的全面指南:从入门到高级【第128篇—Django框架】

👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Django框架的全面指南:从入门到高级 Django是一个高效、功能强大的Python Web框…...

C++类和对象基础

目录 类的认识 访问限定符:public(公有),protected(保护),private(私有)。 类的两种定义方式: 类的实例化: 封装: 类的对象大小的计算: 类成员函数的this指针: C语言是面向过程的语言&am…...

消息队列常见的两种消费模式

一、点对点模式 点对点模式:生产者发送消息到消息队列,消费者从消息队列中接收、处理消息,消息被消费后,就不在消息队列中了。每个消息只能由一个消费者接收和处理。如果有多个消费者监听同一个队列,消息将被发送到其…...

php的伪协议详解

在 PHP 中,伪协议(pseudo-protocols)是一种特殊的语法,用于访问各种资源,如文件、网络、输入/输出流等。伪协议实际上并不是真正的协议,而是一种简便的语法,用于访问不同的资源类型。 以下是一…...

【研发日记】Matlab/Simulink技能解锁(四)——在Simulink Debugger窗口调试

文章目录 前言 Block断点 分解Block步进 Watch Data Value 分析和应用 总结 前言 见《【研发日记】Matlab/Simulink技能解锁(一)——在Simulink编辑窗口Debug》 见《【研发日记】Matlab/Simulink技能解锁(二)——在Function编辑窗口Debug》 见《【研发日记】Matlab/Simul…...

沪深主板打板胜率统计

统计了20100101以来的数据,以中信日K为数据来源。 计算方法: 选出每只股票 (收盘价-开盘价)/开盘价 >0.098的日期,然后往后取3天数据,如果3天内有一天能涨超0.2元,则认为打板成功。 总共打板: 52239次 胜: 43784次…...

Python中的列表推导式(List Comprehension)

Python中的列表推导式(List Comprehension)是一种强大且简洁的语法结构,用于快速创建列表。它通过一行代码就能完成原本需要多行代码才能实现的循环迭代与列表添加操作。列表推导式在Python中非常常用,它使得代码更加简洁、易读和…...

MusicHiFi: Fast High-Fidelity Stereo Vocoding

MusicHiFi: Fast High-Fidelity Stereo Vocoding 相关链接:arxiv github 关键字:音乐生成、高保真立体声、立体声编解码器、生成对抗网络、频带扩展 摘要 MusicHiFi是一种高效的高保真立体声编解码器,它通过将低分辨率的mel频谱图转换为音频…...

完美解决 RabbitMQ可视化界面Overview不显示折线图和队列不显示Messages

问题场景: 今天使用docker部署了一个RabbitMQ,浏览器打开15672可视化页面发送消息后不显示Overview中的折线图,还有队列中的Messages,因为我要看队列中的消息数量。 解决方案: 进入容器内部 docker exec -it 容器id…...

matlab 混沌系统李雅普洛夫指数谱相图分岔图和庞加莱界面

1、内容简介 略 65-可以交流、咨询、答疑 2、内容说明 matlab 混沌系统李雅普洛夫指数谱相图分岔图和庞加莱界面 混沌系统李雅普洛夫指数谱相图分岔图和庞加莱界面 李雅普洛夫指数谱、相图、分岔图、庞加莱界面 3、仿真分析 略 4、参考论文 略...

Linux-docker安装数据库mysql

1、拉去mysql镜像: docker pull mysql2、创建容器挂载路径 mkdir -p /usr/local/jiuxiang/mysql/data # 数据存储位置 mkdir -p /usr/local/jiuxiang/mysql/logs # 日志存储位置 mkdir -p /usr/local/jiuxiang/mysql/conf # 配置文件3、启动容器 docker run -…...

网工内推 | 七险一金,上市公司招信息安全工程师,大牛带队

01 启明星辰信息技术集团股份有限公司 招聘岗位:数据安全服务工程师 职责描述: 1、负责数据安全服务项目的管理,统筹组织并协调资源落实项目交付实施; 3、负责数据安全风险评估、数据分类分级、数据安全管理制度、数据安全体系规划等数据安…...

04.组件的组成和组件间通信

一、scoped解决样式冲突 1.默认情况: 写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。 全局样式: 默认组件中的样式会作用到全局,任何一个组件中都会受到此样式的影响 局部样式: 可以给组件加上scoped 属性,可以让样式只…...

【Sql Server】通过Sql语句批量处理数据,使用变量且遍历数据进行逻辑处理

欢迎来到《小5讲堂》,大家好,我是全栈小5。 这是《Sql Server》系列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对…...

MySQL中group_concat()用法

函数用法见链接处 https://www.cnblogs.com/mcj123/articles/17189384.html 使用过程问题:group_concat()拼接后的字符串长度默认限制为1024位字节,超长会被自动截取。 解决: 修改group_concat限制长度。 1.数据库直接通过sql修改 查询限制长…...

栈队列数组试题(四)——数组和特殊矩阵

01.对特殊矩阵采用压缩存储的主要目的是( D ). A.表达变得简单 B.对矩阵元素的存取变得简单 C.去掉矩阵中的多余元素 D.减少不必要的存储空间解析:特殊矩阵中含有很多相同元素…...

数据结构的概念大合集01(含数据结构的基本定义,算法及其描述)

概念大合集01 1、数据结构基础的定义2、数据结构2.1 数据元素之间关系的集合2.2数据结构的三要素2.2.1数据的逻辑结构2.2.2数据的存储(物理)结构2.2.3数据的运算 3、数据类型4、抽象数据类型类型(ADT)5、算法及其描述5.1算法的5个…...

.NET高级面试指南专题十七【 策略模式模式介绍,允许在运行时选择算法的行为】

介绍: 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。它定义了一系列算法,将每个算法封装到一个对象中,并使它们可以互相替换。这使得算法可独立于使用它的客户端变化。 原理: 策略接口(Strat…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM&#xff09…...

ios苹果系统,js 滑动屏幕、锚定无效

现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...