『 Linux 』网络传输层 - TCP(二)

文章目录

    • TCP六个标志位
    • TCP的连接
      • 三次握手
    • 四次挥手
      • 为什么是三次握手和四次挥手
    • 重传机制

TCP六个标志位

在TCP协议报文的报头中存在一个用于标志TCP报文类型的标志位(不考虑保留标志位),这些标志位以比特位选项的方式存在,即对应标志位为0则表示为假,对应标志位为1则为真;

  • SYN

    用于建立连接,连接发起方发送SYN请求,表示希望发起一个连接,同步序列号;

  • ACK

    标识确认,该位被设置时,确认号字段有效,用于确认接收到的数据;

  • FIN

    用于关闭连接,一方发送FIN表示它已经完成数据发送并希望关闭连接;

  • RST

    用于重置连接,表示当前连接有问题,需要强制断开,通常用于错误或异常情况;

    RST报文被接收后需要重新进行三次握手来建立一个新的连接;

  • PSH

    推送数据,提示接收方应用程序应立即读取数据而不是在缓存中等待更多数据;

    本质上TCP也是一种生产者消费者模型的体现,其中发送方的用户层与接收方上层的用户层各担任了生产者和消费者的身份,其中发送方的用户层作为生产者,接收方的用户层作为消费者,当接收缓冲区满了后发送方再向接收方发出的数据流将被丢弃,在对于流量控制而言本质上就是在网络中的一种同步应用;

    PSH报文可以通过告诉接收方应尽快将这些数据流传给应用层避免数据长时间积累在接收缓冲区中导致接收方的接收缓冲区被写满;

  • URG

    表示紧急数据,紧急指针字段有效,用于标示紧急数据的位置,提示接收方优先处理;

    在操作系统中存在一个专门用于处理紧急数据的空间,当紧急数据被发送过后且URG标志位被设置,表示紧急指针有效,对应的紧急数据将会优先被处理;

    对于TCP而言,其数据流是按序到达的,所以为了不导致大面积的数据乱序,紧急指针所指向的紧急数据很小,通常只有一个字节;

    大部分情况下紧急数据用来处理或者检查对端接收缓冲区中数据长时间不被处理导致的发送方所发送的数据无法被接收方接收导致发送方未接收到应答等情况;

    可以将URG标志位理解为一个优先通道;

    可以通过系统调用接口send()设置对应的MSG_OOB选项来设置紧急数据,对应的也可通过系统调用接口recv()同样设置MSG_OOB选项来读取对应的紧急数据;

六个标志位中每一个标志位都标示着该TCP报文的类型,即一个TCP报文可能是多种类型,如在进行三次握手时,被握手方需要返回一个SYN+ACK的报文,其中该报文中的SYN表示也需要向对方建立起连接,而ACK表示的是对对方发起的SYN报文进行应答;

同时为了保证安全性,操作系统通常不会直接让用户直接修改对应的标志位,但对应的操作系统会为用户提供一些系统调用接口来间接修改报文的属性类型;

如当用户调用connect()系统调用接口向一个服务端发起连接时,本质上是让系统构建一个SYN类型的TCP报文并发送给对端;

对应的当一个已经连接的服务端或是客户端调用close()时本质上也是让系统在底层构建一个FIN类型的报文,并发送给对方表示希望断开该次连接;


TCP的连接

TCP是一个保证可靠传输的网络协议,其为了保证数据传输的可靠性,通常要与服务端建立起连接,但尽管TCP协议制定了若干的约定来保证数据在传输中的可靠性但也避免不了一些不可抗拒的因素;

本质上TCP协议保证可靠传输的前提是在与对端建立连接的前提下,保证未发生不可抗力异常时数据的传输(不可抗力异常通常为断电或设备故障,物理连接中断或是网络设备配置错误,任何一端应用层的崩溃等情况);

通常情况下服务器都是一对多的,即一台服务器将对应存在若干个客户端,当一台客户端向服务器发起连接请求时服务器中可能也在处理来自其他客户端的连接请求或是维护与其他客户端的连接,维护的方式同样的采用的是 “先描述后组织” ,无论是服务端还是客户端为保证连接的可靠性系统层面都要对已经建立好的连接创建一个对应的结构体,通过实例化结构体对象再以特定的数据结构将多个该结构体对象组织在一起,如链表;

对应的任何一端对连接的维护都是具有成本的,即需要花费时间和空间;

  • TCP允许连接建立失败

TCP所保证的可靠性是建立在已经建立连接的基础上,但实际上在建立连接时可能会因为多种因素导致连接建立失败,TCP能保证数据传输可靠但是无法保证在建立连接时能完全避免连接建立失败的情况;


三次握手

TCP协议建立连接时需要先进行三次握手;

所谓三次握手即为,请求建立连接方向对端发送SYN报文表示希望与该端建立连接,对端进行应答并告知也希望与该端建立连接返回一个SYN+ACK报文,请求方向对端返回ACK报文表示接收到对端的请求;

以该图为例:

  • Client向Server发送SYN报文
  • Server向Client返回SYN+ACK报文
  • Client向Server发送ACK报文

其中图中的每次报文发送的斜线表示每次报文的发送与接收具有时间差;

以客户端的视角而言,当客户端发送第三次握手的ACK报文后则表示该次握手已经建立成功,将会创建一个对应的结构体用于管理该连接;

而对于服务端而言,当其接收到第三次握手的ACK报文才表示该次连接真正被建立成功,才会生成对应的结构体对象来管理该连接,当服务端接收到三次握手中的最后一个ACK报文后不会再对该ACK报文进行应答,这也是 “应答不会再被进行应答” ;

即通常情况下对于客户端而言,当其认为连接已经建立成功后将会正常与服务端进行正常通信,若是服务端未接收到最后一个ACK报文就接收到了客户端的正常通行报文(数据流),服务端将会认为该连接并未建立成功,并不会接收该报文,而是向客户端发回一个RST报文告诉该连接并未建立成功,要求客户端重新发出最后一个ACK报文以要求建立连接;

这里也涉及到确认序号的问题,当发送端发出一个TCP报文给接收端,对应的接收端将对该报文向对端返回一个ACK报文表示应答,其中返回的ACK报文中的确认序号通常为 所接受报文序号+有效载荷大小 ,通常SYN标志位和FIN标志位将会占用一个序列号,所以对应的当服务器端接收到一个SYN报文时,假设该报文序列号大小为x,则服务端需要返回一个序列号大小为x+1SYN+ACK报文,示例为如下:

  • 第一次握手

    客户端发送一个SYN报文,假设序列号为x;

    Client -> Server : SYN, SEQ = x
    
  • 第二次握手

    服务器收到SYN报文,返回SYN+ACK报文,假设服务器的初始序列号为y;

    Server -> Client : SYN+ACK, SEQ = y, ACK = x+1
    
  • 第三次握手

    客户端收到SYN+ACK报文,返回ACK报文;

    Client -> Server: ACK, SEQ = x+1, ACK = y+1
    

当应用层想要该端与一个服务器端建立起连接,需要调用connect()系统调用接口使底层构建一个SYN报文,但实际上connect()只负责要求系统构建报文,其函数本身并不参与握手(只发起握手,不关心握手细节);

当一个执行流调用connect()系统调用接口使系统构建SYN报文后将进行阻塞,直到握手完成,当以客户端的视角第三次握手被发出后对应的连接将视为成功,对应的系统将为该连接维护对应的结构体,并且将该连接以套接字描述符的方式返回给connect()函数表示连接建立完成;

对应的当一个服务端需要获取一个来自客户端的连接时同样要调用accept()系统调用接口,同样的该接口不参与握手细节,当一个执行流调用该系统调用接口时对应的该执行流也会进入阻塞状态,直到三次握手完成并且连接被建立成功,对应的该被维护起来的连接将以套接字描述符的方式交给该函数作为返回值;


四次挥手

四次挥手是正常情况下连接断开的过程,通常为申请断开连接方调用系统调用接口close()让系统构建一个FIN报文并发送给对方;

四次挥手的过程为:

  • 第一次挥手

    发送方向接收方发送一个FIN报文表示希望与对端断开连接;

  • 第二次挥手

    接收方向发送方返回一个ACK报文表示接收到这个断开连接请求;

  • 第三次挥手

    接收方向发送方发送一个FIN报文表示希望与对端断开连接;

  • 第四次挥手

    发送方向接收方返回一个ACK报文表示也收到了这个断开连接请求,至此连接彻底断开;


为什么是三次握手和四次挥手

  • 为什么是三次握手

    三次握手是TCP为了保证双方通信时具有可靠性所定制的一种策略;

    而三次握手可以确保客户端和服务端至少都向对方发送了一次消息,从而确保连接建立的更为可靠;

    以朴素的角度来看三次握手实际上也可以被解析成四次握手;

    但为了提升连接创建的效率,TCP采用捎带应答的策略,在第二次握手中将ACK报文与SYN报文整合成了一个报文,即为SYN+ACK报文;

    在三次握手中能够确保双端都对对方进行一次消息的发送以及消息的接收来确保连接的稳定,因此三次握手中任何一次握手都不能少;

    假设三次握手的数量减少,连接的可靠性将大大降低,如以下几种情况:

    • 单次握手

      单次握手时通常为当客户端向服务端发起一个连接请求后服务端无法保证连接的可靠性就直接建立起对应的连接并进行维护,既不能保证客户端向服务端方向的数据传输是否可靠(服务端不进行应答即建立连接,不能保证服务端是否接收到对应的连接请求),也无法保证服务端向客户端方向数据传输是否可靠;

      同时维护连接通常是具有成本的,单次握手可能会导致同一个客户端向一个服务端大量发送连接请求,只要服务端一接收就建立起对应的连接并且对这些连接进行维护,将会大大占用服务端资源;

      一次握手服务端无法确认客户端的状态,无法保证连接的有效性和安全性;

    • 二次握手

      二次握手对于客户端而言,仍无法保证服务器已经准备好通信,二次握手通常意味着客户端发送SYN报文,服务端返回SYN+ACK报文,在未接收到客户端的ACK前服务器就已经认为连接已经成立,但实际上客户端收到SYN+ACK后可能由于种种原因无法进行数据传输,如网络中断等;

      而服务端将会为一个可能无效的连接预留资源,同样会面临无法确认客户端是否通信就绪的问题;

    三次握手将建立一个稳定可靠且能够确保全双工的通信连接,即任意一方都可以有效的进行发送数据和接收数据;

    通常情况下,客户端与服务端的关系通常是一对多的,即一个服务端对应着若干个客户端,而一次握手和二次握手两种方案最终都把负载交到了服务端身上,服务端随时都维护着一些无用资源,即并不进行通信了连接进行维护;

    三次握手可以将负担均匀的双方分配而不是只有单单服务端具有负担;

    同时一次握手和二次握手的方案将大大提升服务端受到SYN Flood(通过发送大量伪造的SYN报文,迫使服务器分配大量资源维护无效连接从而使其无法处理正常请求)等DoS攻击;

    同时三次握手不仅确保了连接的可靠性,三次握手时双方所发的报文也是一种协商报文,协商的包括双方的起始序号,确认序号位置,窗口大小等等;

    同时当任意一端发送RST报文后,表明当前连接被强行中断,任何已建立的连接状态信息都会被销毁,如果需要重新建立通信必须进行新的三次握手,以建立一个全新的TCP连接;

  • 为什么是四次挥手

    三次握手是建立通信连接的过程,而四次挥手是断开连接的过程,断开连接与建立连接是不同的,在连接建立过后数据是双向发送的,客户端和服务端任意一方都既扮演着发送方,也扮演者接收方的角色;

    当一端将数据发送完后准备关闭连接其无法确保对端是否还有数据未发完,所以断开连接的操作通常为四次挥手,即双方在确保没有数据要发送给对方时都要向对方发送连接关闭的请求;

    假设客户端主动向服务端发起断开连接的请求(客户端断开连接请求前的所有数据段已经发送完成),即客户端调用系统调用接close()时系统将生成一个FIN报文发送给对方并进入一个FIN_WAIT_1的状态,即第一次挥手;

    当服务端接收到FIN报文后将无条件进行ACK报文答复,即第二次挥手;

    此时连接并没有断开,只是客户端不再向服务端发送数据,对应的客户端将进入一个FIN_WAIT_2的状态,对应服务端也将进入一个CLOSE_WAIT的状态,这里客户端不发送数据表示不主动发送数据,对于数据的应答客户端还是会照常进行;

    在连接完全断开前也要保证数据传输的可靠,即当客户端一样可以接受来自服务端的数据并且处理对应数据;

    当服务端发送最后一条数据后服务端将主动向客户端发送一个FIN报文,即第三次握手;

    同时服务端能够确认自己没有数据需要再发送给客户端也能确认客户端没有数据再发送给本端,但是其无法保证客户端的数据已经全部处理完毕或是无法保证数据没有丢包,所以连接还是不能断开;

    若是数据段在网络中丢失或是出现其他情况时服务端需要启用重传策略;

    当客户端接收完并处理完所有数据段后将对服务端再次发送一个ACK报文表示确认服务端的连接断开请求;

    至此连接彻底关闭;


重传机制

为了保证数据传输时的可靠性,TCP定制了一系列的重传机制以避免数据丢失,常见的重传机制有快速重传,超时重传,选择性重传和快速恢复;

  • 快速重传

    快速重传用于发送方识别到所发数据丢失从而快速对数据进行重发;

    通常情况下快速重传机制将在接收方返回三个重复的ACK报文时被触发;

    假设发送方向接收方发送三个报文,对应报文的序列号为499,999,1499,将在下面情况发生快速重传;

    • 发送方发送三个报文段

      报文段1 : 序号499

      报文段2 : 序号999

      报文段3 : 序号1499

    • 接收方行为

      接收方接收到序号499报文,返回ACK报文,序号为500;

      接收方未接收到序号999报文,继续等待;

      接收方接收到序号1499报文,因为期望先收到序号999报文,因此发送重复序号为500ACK报文;

    • 发送方行为

      发送方收到第一个序号为500ACK报文,忽略;

      发送方收到第二个重复序号为500ACK报文,怀疑记录丢失,记录第二个重复ACK报文;

      发送方收到第三个序号为500ACK报文,触发重传机制;

    • 触发快速重传

      发送方立即重传丢失的报文段(序号为999);

  • 超时重传

    超时重传是TCP最基本的一种重传机制,通过定时器的方式来决定何时需要重传数据;

    其工作原理为:

    • 发送数据并启动定时器

      发送方再发送一个数据段后会启动一个定时器并记录下此数据段的序列号;

      定时器设置的超时时间通常是由 往返时间 和网络状态估算来的;

    • 等待确认

      发送方等待接收方响应回的ACK报文来确认已经成功接收到该段数据段;

      如果在定时器超时之前收到对应数据段的ACK报文则停止定时器并继续发送后续数据段;

    • 定时器超时并重传

      如果定时器到期时仍未收到对应报文的ACK应答,发送方将在新的定时器周期内重新发送该未经确认的数据段;

      超时时间一般采用 指数回退算法 来避免频繁重传所引起的网络拥塞;

  • 快速恢复

    快速回复机制通常与快速重传机制结合使用,当检测到丢失的数据段时,通过调整拥塞窗口以避免传输速率下降过多;

    • 快速重传后的拥塞控制

      当接收到三个重复的ACK报文并且执行了快速重传后,发送方将窗口大小减半并设置慢启动门限;

      具体来说 : ssthresh = cwnd/2 , 然后 cwnd = ssthresh + 3 * MSS;

    • 继续发送数据

      在快速恢复期间,发送方按照新的cwnd继续发送数据段而不进入漫长的慢启动过程;

      发送新的数据段是为了利用窗口中未消费的部分确保不浪费带宽;

    • 恢复正常传输

      当收到新的ACK报文后,将会把cwnd调整到适当的大小并恢复正常传输;

  • 选择性确认

    选择性确认也被称为SACK;

    可以告知发送方具体那些数据段已经被接收和丢失,前提是通信支持SACK机制;

    假设发送方发送三个报文段,序号分别为200,400(丢失),600;

    • 接收方发送SACK

      接收方接收到序号200的报文段,发送ACK201并附带SACK选项标记接受情况;

      接收方接收到序号600,发送ACK201并在SACK中标记已接收区间以及遗漏部分400-599;

    • 发送方根据SACK重传

      发送方根据SACK选项确认丢失的报文段(序号400-599)并仅重传这部分数据;

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安科瑞AMB400分布式光纤测温系统解决方案--远程监控、预警,预防电气火灾

安科瑞戴婷 可找我Acrel-Fanny 安科瑞AMB400电缆分布式光纤测温具有多方面的特点和优势: 工作原理: 基于拉曼散射效应。激光器产生大功率的光脉冲,光在光纤中传播时会产生散射。携带有温度信息的拉曼散射光返回光路耦合器,耦…

Raspberry Pi 树莓派产品系列说明

系列文章目录 前言 随着我们产品线的不断扩展,要了解所有不同的 Raspberry Pi 板可能会让人感到困惑。以下是 Raspberry Pi 型号的高级分类,包括我们的旗舰系列、Zero 系列、计算模块系列和 Pico 微控制器。 Raspberry Pi 电脑分为几个不同的系列&#x…

电阻电容电感为什么通常是10、22、47这些数

电阻电容电感为什么通常是10、22、47这些数 优先数的来源优先数的优点:E24和E96的来源 我们在选择电阻时,经常看到的阻值是33Ohm,4.7KOhm,1KOhm,680Ohm.基本上是以这几个数字开头。 同时在选择电容时,经常看…

以「JIMUMETA元宇宙体验馆」为例,探讨有哪些元宇宙场景?

让我们以「JIMUMETA元宇宙体验馆」为例,深入探讨元宇宙场景中提供的产品与服务。该体验馆由视创云展精心打造,集成了企业主展馆、元宇宙虚拟活动分会场、品牌展示分会场、线上论坛会场以及会议室接待会客等多重功能,旨在全方位满足企业发布会…

在MacOS玩RPG游戏 - RPGViewerPlus

背景知识 由于我一直使用Mac电脑,所以一直对Mac如何玩RPGMV/RPGMZ游戏的方式有进一步的想法。 网上能给出的方案都是自行启动一个HTTP服务进行,进行服务加载。这个方法有效,但兼容性较差。涉及到自定义功能模块的游戏,都会有报错…

使用Scrapy框架爬取博客信息

随着网络的发展,越来越多有价值的信息存储在网络上。使用爬虫技术可以从这些信息源中提取出有用的数据。本文将介绍如何使用Python中的Scrapy框架来爬取博客站点上的文章标题、作者以及阅读数,并将其保存到JSON文件中。 一、项目背景 Scrapy是一个快速…

【Java Web】使用JDBC操作数据库(含代码示例)

文章目录 JDBC主要组成部分访问数据库步骤数据库交互StatementPreparedStatementSQL注入攻击 演示示例单查询多查询返回记录数 JDBC(Java Database Connectivity)是Java中用于执行SQL语句的标准API,它提供了一种统一的方式来访问各种关系型数…

[CUDA] atomic函数闭坑技巧

文章目录 1. 尽量减少atomic的使用频率2. 小心atomic的不规则读数 cuda atomic函数使用时的一些注意事项 1. 尽量减少atomic的使用频率 由于atomic会增加threads之间的同步性,所以在有选择性的atomic操作时,可以考虑用if(condition) atomic;…

开源全站第一个nextron项目--NextTalk:一款集成chatgpt的实时聊天工具

NextTalk 简介 该项目是一个基于Nextron(NextJSElectron)的桌面端实时聊天工具。 但由于使用了NextJS中的ssr及api route功能,该程序只能在开发环境运行。 关于生产版本:我将其网页端部分分离,并用Pake将其打包成桌面端,生产体…

河南高校大数据实验室建设案例分享

泰迪智能科技在与中国各地高校的合作中积累了丰富的经验,尤其是在大数据和人工智能领域。过去多年里与河南省内多所高校在大数据领域进行了积极的探索和建设,形成了一系列具有特色的大数据实验室。这些实验室不仅促进了高校内部的科研创新,也…

Kafka自动生产消息软件

点击下载《Kafka服务端(含Zookeeper)一键自启软件》 点击下载《kafka客户端生产者消费者kafka可视化工具(可生产和消费消息)》 点击下载《Kafka自动生产消息软件》 1. 前言 在软件开发过程中,Kafka常被用作消息队列来处理特定的业务功能。为…

龙迅#LT8668EX显示器图像处理芯片 适用于HDMI1.4+VGA转4PORT LVDS,支持4K30HZ分辨率,可做OSD菜单亮度调节!

1. 一般说明 LT8668EX 是 Lontium 的第二代 LCD 控制器,基于 ClearEdge 技术,支持 VGA 接口和 HDMI 接口,符合 HDMI 1.4 规范。它可以支持带 HDMI 接口的双模 DP。为了向后兼容,该 LCD 控制器还包括一个高性能模拟接口&#xff0…

分享SRC漏洞挖掘中js未授权漏洞挖掘的小技巧

文章目录 0x1 前言0x2 js未授权简介一、什么是未授权?二、常见的未授权访问漏洞三、js漏洞挖掘需要获取的几个信息四、如何挖掘五、浅谈 0x3浅谈 js未授权挖掘技巧一、常规js未授权挖掘二、浅谈交流 0x4 Findsomething应该怎样正确使用?问题一:findsome…

如何保护网站安全

1. 使用 Web 应用防火墙(WAF) 功能:WAF 可以实时检测和阻止 SQL 注入、跨站脚本(XSS)、文件包含等常见攻击。它通过分析 HTTP 流量来过滤恶意请求。 推荐:可以使用像 雷池社区版这样的 WAF,它提…

内感受性注意的电生理特征:频谱和源定位分析

摘要 对内感受信号的关注和有意识地处理能力被认为对最小自我、适应性自我调节和情感体验的发展,以及工具性和执行性认知功能的最佳表现至关重要。然而,尽管关于内感受推论解释的理论非常丰富,但实证证据仍然很少。在此基础上,本…

[OPEN SQL] FOR ALL ENTRIES IN

FOR ALL ENTRIES IN 语句用于从一个内部表中检索与另一个内部表中指定字段匹配的记录 语法格式 SELECT ... FOR ALL ENTRIES IN <itab> WHERE <cond>. <itab>&#xff1a;插入目标数据内表 <cond>&#xff1a;查询条件 使用FOR ALL ENTRY IN 语句时&…

GetX的一些高级API

目录 前言 一、一些常用的API 二、局部状态组件 1.可选的全局设置和手动配置 2.局部状态组件 1.ValueBuilder 1.特点 2.基本用法 2.ObxValue 1.特点 2.基本用法 前言 这篇文章主要讲解GetX的一些高级API和一些有用的小组件。 一、一些常用的API GetX提供了一些高级…

Windows下基于fping进行批量IP测试

fping是Linux下一个很好用的IP测试工具&#xff0c;结合代码可以完成批量的IP测试&#xff0c;在网络调试中用途很广。本文是基于fping for Windows结合bat批处理&#xff0c;定制的测试脚本样例。 一、程序信息 本次测试使用fpingV5.1 for Windows版&#xff0c;版本信息如下…

[MRCTF2020]你传你呢

[MRCTF2020]你传你&#x1f40e;呢 审题 一眼文件上传 知识点 .htaccess文件的作用 <FilesMatch "a.png"> SetHandler application/x-httpd-php </FilesMatch>将a.png当做php文件执行 AddType application/x-httpd-php .jpgAddType 是一个 Apach…