TCP的一些功能详述

news2024/12/23 13:41:34

 文章制作不易,望各位大佬多多点赞,球球各位啦!!!!

目录

1.TCP的简介

2.TCP协议中部分数据的理解

1.端口号

2.序列号

3.四位首部长度

4.6位保留位

5. 16位校验和

6.数据(TCP的载荷)     

3.TCP如何实现可靠传输

1.确认应答

2.超时重传机制

3.连接管理

三次握手

四次挥手

小结

4.TCP如何优化因可靠传输造成的效率降低 

1.滑动窗口

流量控制

拥塞控制

(PS:流量控制和拥塞控制在实际情况下是联合使用的,会取他们俩之间的最小值) 

2.延时应答

3.捎带应答

5.TCP对特殊异常场景的解决

1.进程崩溃

2.主机关机

3.主机掉电

4.断网

6.TCP因为面向字节流引出的粘包问题

总结:


1.TCP的简介

TCP全称传输控制协议(Transmission Control Protocol)。它是传输层的协议。

TCP拥有以下属性:。

1.TCP是有连接的

2.TCP是可靠性传输

3.TCP是面向字节流的

4.TCP是全双工的

TCP协议相较于其他协议来讲最主要的是实现了一个非常可靠的传输。

以下图中很大一部分的空间都是为了实现可靠传输。那接下来我们开始了解TCP吧!

2.TCP协议中部分数据的理解

1.端口号

TCP中记录了源端口号和目的端口号,它们分别都是16位的。这是数据传输到目的地的基础。很好理解。这就相当于去网吧点外卖外卖,你的座位号。没有座位号他就不可能送到你的面前。

2.序列号

因为TCP是面向字节流的,所以每一个字节都会有自己的编号,以便接下来的传输以及排序,后面我们会讲到,这个序列号还可以解决流量控制里的收未收到问题。序列号的工作原理就是发送端发送信息到接收端,接收端就会返回一个应答报文,应答报文里的确认序号就会向发送端索要序列号加一的数据。

而发送端的序列号一般也不会是1,在后面的连接管理中我们会讲到。

3.四位首部长度

这里和UDP协议不同,UDP是16位报文长度,而TCP是首部长度。这里的首部长度是指报头信息的长度。那有的长的帅的哥们就会问了“不是哥们儿?看着上面的图,不算上选项的大小都已经有20字节的大小,但是4个bit最大就只有15个字节的大小,这怎么够放?”。这是因为他代表的首部长度是乘以4之后的长度。也就是说首部最长是60个字节,那也就是说选项的大小必须是4的倍数,最大只能是40byte。

4.6位保留位

这里的六位保留位就是为了防止因为某些字段限定了大小导致在未来使得某些功能实现的很麻烦。

就如UDP就是因为最大报文长度为16个字节导致传送的信息最大就只有64kb。而现在很多信息都已经超过了64kb大小,所以使用UDP就会产生一些很麻烦的事情,就比如说要发送大于64kb的信息,那么就要程序员在应用层方面进行拆包和组包,对我们的开发效率产生了很大的影响。

5. 16位校验和

我们发送数据的时候为了防止我们发送的数据因为外界环境影响而改变,TCP引入了校验和机制。在发送数据之前,TCP会计算出整个报文的校验和,并且将这个校验和存到16位校验和中。待数据发送到接收端时,接收端会重新计算校验和,如果相同,那么就没什么问题,如果不同则接收端会抛弃这个数据并且触发重传功能。当然校验和的方式也不止一种,最常见的就是CRC(循环冗余校验),MD5(Message-Digest Algorithm 5),SHA1(安全哈希算法1) 。其中MD5还被广泛用于密码学(它具有以下三点性质:1.无论什么数据结果都是定长的。2.分散性,数据只要发生一点点改变结果就会发生很大的改变。3.不可逆性,他的运算是一个单向的过程,目前的算力基本无法对MD5进行解密)。   

6.数据(TCP的载荷)     

因为TCP是面向字节流的,所以数据的大小本身没有什么限制。但是他会受像MTU(最大传输单元) ,MSS协商(三次握手之后确定的最大窗口大小),操作系统限制和应用程序设置。

3.TCP如何实现可靠传输

TCP协议最核心的就是它实现了可靠传输。可靠传输不是指信息百分之百能传输到接收端,而是尽量保证数据能够完全有序地无错地传到接收端去。那为什么不是百分之百呢?这是因为TCP再怎么厉害也只是传输层地协议,在它的更底层出现问题,就比如物理层的光纤断了,无论你这个协议写的再好,也不可能传到接收端了。那我们大概了解了以下什么叫可靠传输,我们再了解一下TCP协议是怎么实现可靠传输的。

1.确认应答

确认应答机制就是当我们的发送端A如果想要发送一条信息给接收端,它就会将这个信息通过网络传送到接收端B。但是这个时候A并不知道B到底收到信息了没有,所以为了让A知道B接收到了信息,B会发送一条没有商业性数据的报文(应答报文)ACK(acknowledge)来告诉A它已经收到了这条信息。

 确认应答机制是TCP实现可靠传输的核心机制,后面很多机制都是建立再确认应答之上的,所以确认应答机制很关键。

这里的ACK数据用报文段里的ACK标志符表示

2.超时重传机制

如果在发送端发送信息到接收端的途中数据应为某些原因丢失了。此时接收端没有接收到信息,就不会返回ACK,那丢了怎么办呢?这时候TCP就引入了超时重传机制。在发送端没有接收到ACK一段时间后,那么这时候发送端就认为是自己的数据丢了,它就会重新发送这段数据。如果过一段更长的时间还没收到,那就再次重发,等待时间就会更久,如此循环。在一定时间内一直没有收到ACK,那么接收端就会认为这个连接已经挂了,接收端就会自行断开连接。这里还有一个问题,如果第一条数据只是在路途中耽搁了一会,但是这时候已经触发了超时重传了,此时两条消息都会发到接收端里去,这时候怎么办呢。制定TCP协议的大佬早就想到了这个问题,他们为TCP设置了一个缓存区。发送来的数据都会先在缓存区里排队,在缓存区内,TCP就会对这些数据进行去重操作。那怎么分辨是否是同一串数据呢,这里我们就会用到前面讲的序列号了,TCP会在缓存区内把相同序列号的数据去掉。也就达成了去重的效果。当然缓存区还有一些功能,就比如我们在后面会讲到的自动排序功能。

3.连接管理

我们在前面说到,TCP协议是带连接的。那连接是什么呢?在这里连接是抽象的概念,表示发送端和接收端互相记录了彼此的信息。就像是结婚一样,领结婚证就是彼此建立连接,双方都留下了结婚证,也就是彼此的信息,当要离婚时,也得双发拿着结婚证去民政局办理。

说到连接就逃不开连接管理的核心内容,3次握手和4次挥手(虽然英文都是shake hands,但是中文翻译成这样更好理解,毕竟握手表示见面,挥手表示离别)。

三次握手

三次握手的流程可以用下图来描述:

A(请求连接端)向B(接收端)发送SYN(同步报文)来请求B的连接,这时候B就会返回ACK应答报文表示已接收到请求同意连接,然后B会向A发送建立连接的请求,A就会返回ACK表示收到请求同意连接。这时候连接就建立成功了。这时候有的长得帅的大哥就会问了“这里明明是4个步骤啊,怎么会是3次挥手呢?误导读者是吧,你给我去SPA!!!”。我看你是完全不懂哦!这里B返回的ACK和SYN可以合并成一个,这样就可以减少网络传输的数据量了,加快了连接的效率,那么3次握手的图就变成了下面这样:

这不就刚好符合三次嘛。那这三次握手有什么意义呢?我们可以对比我们平常打电话的时候:

 

映射到三次握手上就是:

1.投石问路,确保网络状态是好的

2.确保发送端和接收端的发送功能和接收功能是好的

3.可以商量一些数据和协议的细节内容,如序号从什么时候开始,窗口的最大大小。

这里我们着重解释一下为什么要商议序列号从什么时候开始。请看大屏幕:

在Java中ServerSocket建立好时就已经服务器就处于LITEN状态了,建立好之后服务器就处于ESTABLISH阶段了

四次挥手

相反于三次握手的建立连接过程,四次挥手也就是断开连接的过程。大致原理如下图:

 

过程与3次挥手差不多,我们这里就不在过多叙述。但是这里有个小问题,B这里的ACK和FIN为什么没有合并在一起呢?这是因为在一般情况下A请求断开连接之后B会返回ACK,但是此时B这边一般还要执行一些收尾工作,所以不会急着发送FIN,而是善后工作结束之后再发。所以我们这里就不能直接合并在一起。但是也有能合并的情况,我们会在后面的延迟应答和捎带应答里面会讲这种情况。

这里还有一个比较重要的断开连接中间状态。如图:

小结

TCP完成这些可靠传输的操作要付出很多效率的代价。

4.TCP如何优化因可靠传输造成的效率降低 

上面我们讲到TCP为了可靠付出了很大的代价,所以TCP为了弥补效率的降低加入了很多优化的机制(PS:虽然优化能大大提升传输效率,但是再怎么优化速度也不可能比过TCP这种不可靠传输)。接下来我们来讲讲这些优化措施。

1.滑动窗口

滑动窗口就是让TCP发送数据不再是一应一答,而是多问多达。先发送出一条消息看看接收缓冲区还有多少空间(后面会讲),然后根据接收缓冲区的大小一并把数据发送过去如图:

当服务器接收到一个数据之后就会返回ack,如若其中一个ack丢了也没事,下一个ack如果能返回就能代表我之前的数据都已经传输到达。就比如下一个是2001这条ack丢失,但是返回了3001ack,那么就表明服务器之前的数据都接收到了。当然如果是第一条丢了,发送端这里就会触发超时重传,重新发送。如果是传输途中数据丢了,那么服务器也会一直索要当前序列号数据。就比如2001丢了,发送端还发送了3001~4000,那么服务器不会读取这条数据而是把它留在缓冲区,然后一直返回ack索要2001这条信息。这里一次性发送的数据多少就是窗口的大小。那为什么叫滑动窗口呢,滑动体现在如果第一条信息解决了,服务器就会继续往后读取信息,就像窗口在滑动一样。那么是不是窗口越大越好呢?且不说有窗口大小的限制。一次性传输的数据过多也会导致数据在发送途中容易丢失。所以这时候我们就引入了流量控制。

流量控制

流量控制能动态的控制窗口的大小,在信息发送到服务器时,服务器的ack还会返回缓冲区的大小(用缓冲区的大小来衡量服务器处理数据的能力)。这时候发送端就会控制这次发送的数量,当缓冲区满了时,发送端就不会发送商业数据了。但是为了知道服务器的缓冲区是否已有空间继续发送信息,发送端会每隔一段时间就发送探测数据报来让服务器返回缓冲区的空间。

拥塞控制

流量控制在服务器角度考虑了发送窗口的大小,而我们还需要考虑路径的数据处理能力。不同的路径上的数据处理装置处理数据的能力不一样,这样我们就很难直接判断出发送的数据多少。所以TCP采用拥塞控制,用实验的方法来判断当前的窗口大小。那么大致上就是先缓慢的发送数据,然后速度不断地变快,当丢包时,就减小窗口大小,当不丢包一段时间时又加大窗口大小,如此循环,达到动态平衡。以下是拥塞控制窗口大小和时间的关系图:

但是这种方案在现在已经落伍了,因为当丢包时一下子把窗口大小变到最小然后再重新增大到设定值很影响效率,所以现在的方案大部分是如下图所示:

(PS:流量控制和拥塞控制在实际情况下是联合使用的,会取他们俩之间的最小值) 

2.延时应答

延时应答机制是为了优化滑动窗口的。如若没有延时应答,发送端发送信息到接收端,接收端还来不及处理数据就要返回ACK,这导致缓存区可能一下就满了,所以为了给接收端处理数据的时间,TCP让接收端收到数据之后过一段时间再返回ACK,这样数据就先被接收端处理一会之后再返回ACK。这样返回的缓存区空间就会变大,就可以请求更大的窗口。

3.捎带应答

捎带应答建立在延时应答之上,当有多条数据发送过来时,如果每个ACK都返回就会给网络传输带来压力。正因为接收端有延时应答,可以先等待一会,等待一些数据发送到了再合并把ACK返回。但是这个等待时间时有上限的,超过时间必须发送ACK,否则会影响TCP的传输,还可以引起发送端的超时重传功能。

正因为有捎带应答,有时候要断开连接,断开连接的发起者A发送FIN到被断开者B时,B会等一会会再返回ACK,如果此时进程的善后工作刚好做完了,那么就会触发捎带应答机制,把ACK和FIN一同返回到A,那么A就能返回ACK与B正常断开连接了。如图:

这就是捎带应答。

5.TCP对特殊异常场景的解决

1.进程崩溃

如果进程崩溃,进程就会结束,因为TCP的连接和进程时相互独立的,所以进程崩溃的这一端的服务器就会发送FIN,接收端会返回ACK和FIN,发送端照样会返回ACK。也就是正常的四次挥手过程。

2.主机关机

如果主机关机,进程照样会先结束,此时关机这一端就会先发出FIN,此时接收端就会返回ACK和FIN,如果此时系统还没关机,那么就会返回ACK,也就是执行完四次挥手才断开了。但如果此时系统已经关机,那么接收端就一直等不到ACK,这时就会触发超时重传,因为已经关机,所以一直没人处理ACK,重传几次后就会进入复位重置状态,但是还是复位不了啊,毕竟关机了嘛,所以最后实在没辙,接收方就放弃了这个连接。

3.主机掉电

如果主机掉电,进程和系统都直接没了,如果此时对端正在发送消息,但是一直没有回应ACK,就会触发超时重传,复位重置,和断开。如果这个时候对端正在接收信息,一直没有动静,此时TCP的另一个机制就出现了,叫做心跳包机制。对端会不定时的向客户端发送探测包,如果没有回应多次,就会视为这个连接已经挂了,那么对端自然会断开连接。

4.断网

和掉电类似,如果断网了,客户端和服务器都是可以运行的,只不过消息发不过去,客户端会触发超时重传机制,复位重置,然后断开。对端会发送心跳包,没回应次数多了也会自动断开。

6.TCP因为面向字节流引出的粘包问题

因为tcp是面向字节流的,所以应用程序只会在缓冲区里看到一个个字节,应用程序又不知道怎么把这些字节分开,这时候就出现了粘包问题。如图:

这时候就需要我们程序员加一个分隔符或者定一个协议(如xml,json,protobuff),让应用程序能够正确的从缓存区中读取数据。

如加一个'\n'如图:

这样我们就可以让应用程序分清楚怎么读取数据。

其中xml,json分别是下图的一种表达形式,而protobuff是把数据转化成二进制进行传输,这里我们不过多讲解。

总结:

TCP真的是一个值得深究的协议,在RFC中对他制定的规则有80多页,我讲的虽然是重点但是也只是冰山一角。

这篇文章写的真的非常非常非常非常辛苦,希望各位大佬们能多多点赞关注支持一下,球球你们啦!!!!          

 

                                                                                          

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

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

相关文章

upload-labs第九十关

第九关 $is_upload false; $msg null; if (isset($_POST[submit])) {if (file_exists(UPLOAD_PATH)) {$deny_ext array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml"…

HarmonyOS Next 悬浮窗拖拽和吸附动画

介绍 本示例使用position绝对定位实现应用内悬浮窗,并且通过animateTo结合curves动画曲线实现悬浮窗拖拽跟手和松手吸附边缘的弹性动画效果。 效果图预览 使用说明 按住悬浮窗可以拖拽,松开后悬浮窗自动靠左或靠右,如果悬浮窗超出内容区上…

【C++】深度解析--拷贝构造函数(从0开始,详解浅拷贝到深拷贝,小白一看就懂!!!)

目录 一、前言 二、拷贝构造函数 🍎概念解析 🥝特性解析 💦为什么拷贝构造函数使用传值方式会引发无穷递归调用? 💦为什么拷贝构造函数的形参中要加入 const 修饰 💦若未显式定义,编译器会生…

c语言,单链表的实现----------有全代码!!!!

1.单链表的定义和结构 单链表是一种链式的数据结构,它用一组不连续的储存单元存反线性表中的数据元素。链表中的数据是以节点的形式来表示的,节点和节点之间相互连接 一般来说节点有两部分组成 1.数据域 :数据域用来存储各种类型的数据&…

深入理解同步与异步编程及协程管理在Python中的应用

文章目录 1. 同步与异步函数的对比1.1 同步函数1.2 异步函数1.3 对比 2. 管理多个协程与异常处理2.1 并发执行多个协程2.2 错误处理2.3 任务取消 本文将探索Python中同步与异步编程的基本概念及其区别。还会详细介绍如何使用asyncio库来有效管理协程,包括任务的创建…

一文读懂uniapp中的tabBar底部导航

目录 1. 基本知识2. Demo 1. 基本知识 UniApp 中的 tabBar 是用来在应用程序底部显示可切换的选项卡的组件,通常用于实现底部导航栏 允许用户通过点击不同的选项卡来切换应用程序的不同页面或功能模块 其代码如下: "tabBar":{"color&q…

UOS系统-mips架构---Java环境安装

平时都是在windows系统上安装的java环境,今天需要在uos系统安装java1.8的环境,记录一下安装过程。 (以下均在root权限下运行) 一、查找java1.8 jdk版本 apt search openjdkopenjdk-8-jdk/未知,未知 1.8.0.212-2deepin mips64el O…

车载摄像头画质增强解决方案,赋能智能驾驶新时代

在智能化浪潮席卷汽车产业的今天,车载摄像头作为智能驾驶的“眼睛”,其画质清晰度直接关系到车辆感知环境的准确性和驾驶的安全性。然而,面对复杂多变的行车环境,如何确保车载摄像头在不同场景下都能呈现出高质量的图像&#xff0…

分布式调度平台xxl-job

1.xxl-job介绍 xxl-job 是一个轻量级分布式任务调度框架,支持动态添加、修改、删除定时任务,支持海量任务分片执行,支持任务执行日志在线查看和分页查询,同时支持任务失败告警和重试机制,支持分布式部署和高可用。xxl…

一文弄懂Seaborn绘制热力图

1. 引言 在本文中,我们将使用Seaborn库来以heatmap热力图的形式来表示数据。我们将重点介绍如何创建它,以及如何更改其颜色,调整对应字体大小等等。 闲话少说,我们直接开始吧! 2. 什么是热力图? Heatma…

Python 数学应用(四)

原文:zh.annas-archive.org/md5/123a7612a4e578f6816d36f968cfec22 译者:飞龙 协议:CC BY-NC-SA 4.0 第十一章:其他主题 在本章中,我们将讨论一些在本书前几章中没有涉及的主题。这些主题大多涉及不同的计算方式以及优…

向量数据库与图数据库:理解它们的区别

作者:Elastic Platform Team 大数据管理不仅仅是尽可能存储更多的数据。它关乎能够识别有意义的见解、发现隐藏的模式,并做出明智的决策。这种对高级分析的追求一直是数据建模和存储解决方案创新的驱动力,远远超出了传统关系数据库。 这些创…

C代码编译过程与进程内存分布

C代码编译过程 在这篇文章中,我们将探讨C语言代码的编译流程以及进程在运行时的内存布局。编译过程通常包括几个关键步骤:预处理、编译、汇编和链接。 预处理阶段主要是处理源代码文件中的宏定义、头文件包含和条件编译指令。在此阶段,编译…

ping命令的使用

一、实验环境 同实验案例分析ARP解析过程环境。 二、需求描述 熟悉 ping 命令的用法并熱悉 ping 命令的各种参数 三、推荐步骤 分别 ping 一个存在的和不存在的IP地址,观察返回的信息分别测试 ping 命令的相关参数。 四、实验步骤 1.ping 一个存在的和不存在…

工业电脑在ESOP工作站行业应用

ESOP工作站行业应用 项目背景 E-SOP是实现作业指导书电子化,并统一管理和集中控制的一套管理信息平台。信迈科技的ESOP终端是一款体积小巧功能齐全的高性价比工业电脑,上层通过网络与MES系统连接,下层连接显示器展示作业指导书。ESOP控制终…

FPGA - ZYNQ 基于EMIO的PS和PL交互

前言: Xilinx ZYNQ系列的芯片,GPIO分为 MIO 、EMIO、AXI_GPIO三种方式。 MIO :固定管脚,属于PS端,也就是ARM端。 EMIO :通过PL扩展,使用时需要分配PL(FPGA)管脚,消耗PL端资源。…

redis-plus-plus的安装与使用

文章目录 一、安装第一步:安装hiredis第二步:安装redis-plus-plus第三步:将编译后的可执行文件移动到/usr/local对应目录第四步:更新动态库 二、使用第一步:编写示例代码第二步:编译运行 本文参考自 redis-…

Pytest测试用例中的mark用法(包含代码示例与使用场景详解)

在软件开发中,测试是确保代码质量和功能稳定性的重要环节。Python作为一门流行的编程语言,拥有丰富的测试工具和框架,其中pytest是其中之一。pytest提供了丰富的功能来简化测试用例的编写,其中的mark功能允许我们对测试用例进行标…

Pytest精通指南(16)利用skip、skipif跳过用例执行

文章目录 前言skip源码分析skip装饰方法skip装饰类skip装饰模块skipif源码分析skipif装饰方法skipif装饰类skipif装饰模块拓展-用例内部跳过执行 前言 skip: skip用于无条件地跳过测试用例,无论测试环境的状态或条件如何。通常用于那些在任何情况下都不应该执行的测…

idea使用plantuml插件报错(类图):Dot Executable: /opt/local/bin/dot

报错提示: 解决方式: 方式一: 直接设置Remote Rendering即可 (使用服务器地址) 无特殊要求可直接使用默认提供的服务地址,也可自行搭建服务替换地址。 自行搭建服务可参考: 在本地Windows 11 系统的桌面…