『 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.xdnf.cn/news/4174.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Django学习-项目部署

WSGI定义: uWSGI定义: 安装uWSGI: 配置uWSGI: uWSGI常见问题汇总: 安装nginx: 配置: 启动/停止dnginx 修改uWSGI配置: 常见问题解决方法: nginx静态文件配置&#xff…

迅为RK3588开发板Android多屏显示之多屏同显和多屏异显

迅为RK3588开发板是一款低功耗、高性能的处理器,适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用,RK3588支持8K视频编解码,内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像…

QML项目实战:自定义Button

目录 一.添加模块 ​1.QtQuick.Controls 2.1 2.QtGraphicalEffects 1.12 二.自定义Button 1.颜色背景设置 2.设置渐变色背景 3.文本设置 4.点击设置 5.阴影设置 三.效果 1.当enabled为true 2.按钮被点击时 3.当enabled为false 四.代码 一.添加模块 1.QtQuick.Con…

基于C#实现Windows后台窗口操作与图像处理技术分析

在Windows编程中,操作后台窗口是一项复杂而有用的技术。它可以用来自动化用户界面测试、应用程序机器人等场景。本文将深入探讨如何在C#中绑定后台窗口、获取后台窗口界面图片,以及在图片中寻找指定图标并获取坐标。本技术文章结合最先进的资料与实践经验…

数据库基础(1) . 关系型数据库

1.数据库 database 1.1.数据持久化 数据持久化(Data Persistence)指的是将程序中的数据保存到某种持久化的存储介质(如硬盘、SSD、磁带等)上的过程,使得即使在程序终止后,数据依然可以被保留下来并在下次…

Python学习的自我理解和想法(27)

学的是b站的课程(千锋教育),跟老师写程序,不是自创的代码! 今天是学Python的第27天,学的内容是python操作pptx和pdf,但是这节博客只会介绍如何新建pptx和加密pdf。开学了,时间不多&…

鸿蒙移动应用开发-------初始arkts

一. 什么是arkts ArkTS是HarmonyOS优选的主力应用开发语言。 ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,保持了TS的基本风格,同时通过规范定义强化开发期静态检查和分析,提升程序执行稳定性和…

Linux(CentOS)安装 JDK

1、下载 JDK 官网:https://www.oracle.com/ 2、上传 JDK 文件到 CentOS,使用FinalShell远程登录工具,并且使用 root 用户登录 3、解压 JDK 创建目录 /export/server mkdir -p /export/server 解压到目录 /export/server tar -zxvf jdk-17…

qt QStandardItemModel详解

1、概述 QStandardItemModel是Qt框架中提供的一个基于项的模型类,用于存储和管理数据,这些数据可以以表格的形式展示在视图控件(如QTableView、QTreeView等)中。QStandardItemModel支持丰富的数据操作,包括添加、删除…

SpringBoot框架在在线教育领域的应用

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示: 图4-1系统工作原理…

【论文分享】基于多源大数据的高密度城市健康资源可达性与公平性评价

评估城市健康设施的可达性和公平性对于有效配置城市健康资源至关重要。本次我们给大家带来一篇SCI论文的全文翻译。该论文从新的视角定义和分类城市中的健康相关设施,考虑居民的主动和被动健康寻求行为,构建一个综合性框架来评估健康设施的邻近性、互补性…

Vue学习之路17----事件

可以自定义事件让子组件向父组件传值 1.使用emit 2.使用props 3.使用mitt 其实mitt和第一种方法类似,都用emitt事件,但是mitt不局限于父子之间通信,他可以在任意2个组件之间通信, 虽然需要安装,但mitt很小&#xff…

基于梯度的快速准确头部运动补偿方法在锥束CT中的应用|文献速递-基于深度学习的病灶分割与数据超分辨率

Title 题目 A gradient-based approach to fast and accurate head motion compensation in cone-beam CT 基于梯度的快速准确头部运动补偿方法在锥束CT中的应用 01 文献速递介绍 锥束计算机断层扫描(CBCT)系统在灵活性方面比螺旋多排探测器计算机断…

基于 JavaWeb 的宠物商城系统(附源码,文档)

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

Redis学习:BitMap/HyperLogLog/GEO案例 、布隆过滤器BloomFilter、缓存预热+缓存雪崩+缓存击穿+缓存穿透

Redis学习 文章目录 Redis学习1、BitMap/HyperLogLog/GEO案例2. 布隆过滤器BloomFilter3. 缓存预热缓存雪崩缓存击穿缓存穿透 1、BitMap/HyperLogLog/GEO案例 真实需求面试题 亿级数据的收集清洗统计展现对集合中数据进行统计,基数统计,二值统计&#xf…

【论文速读】| PathSeeker:使用基于强化学习的越狱攻击方法探索大语言模型的安全漏洞

基本信息 原文标题: PathSeeker: Exploring LLM Security Vulnerabilities with a Reinforcement Learning-Based Jailbreak Approach 原文作者: Zhihao Lin, Wei Ma, Mingyi Zhou, Yanjie Zhao, Haoyu Wang, Yang Liu, Jun Wang, Li Li 作者单位: Beihang University, Nany…

P2672 [NOIP2015 普及组] 推销员

P2672 [NOIP2015 普及组] 推销员 难度: 提高/省选- 。 考点:贪心、前缀和。 题意: ​ n n n 个住户,小明每走一米消耗 1 1 1 疲劳,第 i i i 个住户距离起点 S i S_i Si​ 米,同时走进住户沟通会累积…

软件工程技术专业在物联网应用开发中的关键技术与挑战

引言 物联网技术的蓬勃发展与广泛普及,极大地丰富了人们的日常生活,催生了诸如智能家居、智能交通、智能健康等一系列创新应用,为用户提供了更加智能化、个性化的服务体验。然而,物联网应用开发也随之迎来了诸多挑战,…

基于Multisim光控夜灯LED电路带计时功能(含仿真和报告)

【全套资料.zip】光控夜灯LED电路设计Multisim仿真设计数字电子技术 文章目录 功能一、Multisim仿真源文件二、原理文档报告资料下载【Multisim仿真报告讲解视频.zip】 功能 光控夜灯LED电路 1.采用纯数字电路,非单片机。 2.通过检测周围光线,光线暗自…

vue 3:监听器

目录 1. 基本概念 2. 侦听数据源类型 1. 监听getter函数 2. 监听 ref 或 reactive 的引用 3. 多个来源组成的数组 4. 避免直接传递值!!! 3. 深层侦听器 4. 立即回调的侦听器 5. 一次性侦听器 6. watchEffect() 7. 暂停、恢复和停止…