【Java网络编程】TCP核心特性(下)

1. 拥塞控制

拥塞控制:是基于滑动窗口机制下的一大特性,与流量控制类似都是用来限制发送方的传送速率的

区别就在于:"流量控制"是从接收方的角度出发,根据接收方剩余接收缓冲区大小来动态调整发送窗口的;而"拥塞控制"是从网络的拥堵状态出发,衡量当前网络拥塞程度从而动态调整拥塞窗口大小的

image.png
如上图所示:接收方和发送方并不是简单直接相连的,路径中间存在着多个通信设备(路由器、交换机等),因此传输过程网络环境错综复杂,因此就算接收方此时剩余接收缓冲区空间足够,发送方的发送窗口值较大也是不合理的!此时我们就需要一套合理的机制来得出针对当前网络拥堵状态、合适的发送窗口大小:也被称为 拥塞窗口
拥塞窗口调整过程

  • 首先是 慢启动 过程:即一开始拥塞窗口(后续写为cwnd)设立一个比较小的值,因为刚开始时网络状态未知,如果开始就设定一个较大值,可能会让本就不富裕的网络带宽雪上加霜
  • 慢启动过程中,拥塞窗口的大小是 指数增长 的,如果没有丢包就让cwnd变为原来两倍(这样做是因为一开始cwnd值较小,指数增长可以快速提高发送效率)
  • 指数增长不会一直持续下去,达到阈值(后续写为ssthresh)之后就转变为 线性增长(这样做的好处是尽可能保持较高的传输速率,并且不会立刻造成拥堵丢包情况)
  • 线性增长也终究还是在增长,当出现丢包情况,就说明此时的网络情况拥堵,就将 新阈值 设定为出现丢包cwnd值的一半,并且让cwnd重新置为一个较小值继续开始慢启动过程

image.png
其中因超时重传导致cwnd减少有两种版本:

  • 一种是TCP Reno版本:新的拥塞窗口值不会将为1,而是从新的ssthresh开始,然后保持线性增长
  • 另一种是TCP Tahoe版本(已废弃):新的拥塞窗口值为1,慢启动过程仍为指数增长,阈值到达新的ssthress值则转变为线性增长

2. 延迟应答

延迟应答:是基于TCP的"滑动窗口"机制以及"流量控制"机制,为了进一步提高传输效率的,它的核心就在于接收方收到数据之后,不会立刻返回Ack报文,而是等待一会(留给应用程序处理接收缓冲区的数据),此时可以回馈的剩余接收缓冲区容量更多了,就可以适当增加发送窗口的大小
image.png
通过滑动窗口机制来传输数据,这里的"延迟应答"的方式类似于按照"ACK报文丢了"的情况进行处理,即接收方连续收到多个ACK报文后,不会每一个都发送ACK报文,而是等待一段时间,例如100ms,然后再返回最后一个ACK报文,此时不仅能够起到"延迟应答"的作用,还可以减少数据传输量

需要注意:这里并不是单纯的按照每隔多少个ACK,返回一个ACK报文,也是和相应的时间间隔相关的,例如每隔2个报文,时间间隔为200ms(不需要记住具体数值,这些都是参数,重要的是理解策略)

3. 捎带应答

捎带应答:是基于"延迟应答",进一步提升传输效率的机制,其核心思想就是尽可能将可以合并的数据报进行合并,从而起到提升效率的作用
我们最常见的通讯模型就是如下"一问一答型"的:
image.png
按照之前的方式:那么当客户端给服务器发送请求后,服务端先返回ACK表示收到了,然后进行业务逻辑处理,返回响应结果response,但是由于 延迟应答机制 的加持,我们在一定条件下可以将ACK报文同response应用层数据报文一起发送(因为ACK报文只将ACK标志位置为1,不会与应用层报文其他内容冲突)

此后后续所有的ACK应答报文都可能和应用层数据报文合并一起发送!也让后续四次挥手变成三次挥手提供可能性!

4. 面向字节流

粘包问题:这里重点讨论"面向字节流"中一个重要话题——粘包问题
结合之前的内容进行理解,这里的包指的是"应用层数据包",即TCP数据到达内核的接收缓冲区后,应用程序会调用socket.receive()进行读取,此时就会出现一个问题,TCP是面向字节流的,因此传输的数据可以看做是一连串字节数据,无法区分包与包之间的边界,例如一个包传送"aaa",另一个包传送"bbb",但是到了接收缓冲区呈现的形式就是"aaabbb",这个问题就是"粘包问题"
解决思路
"粘包问题"并不是TCP独有的,而是所有的面向字节流的协议都会产生的,解决的思路大体有如下两种:

  1. 通过特殊符号,作为分隔符,每次遇到分隔符就表示达到包结尾了,例如我们传输数据后面加上分隔符"\r\n",那么上述情况中接收缓冲区的数据就是"aaa\r\nbbb\r\n",此时我们就有办法进行区分了
  2. 另一种思路就是占用额外的存储空间用来存放该数据包的长度,例如上述情况我们可以表示为"[3]aaa[3]bbb",此时我们读取的过程中就已知长度进行分隔读取了

5. 异常处理

异常情况:上述我们讨论的都是基于TCP正常状况下的网络传输过程,唯一存在的异常情况也就是"丢包"了,但是如果出现更为严重的故障呢?TCP会如何处理呢,这就是该特性需要讨论的地方:
异常情况分类

  1. 发送方或者接收方出现了进程崩溃:

    进程无论是正常结束还是异常崩溃,都会触发 文件资源回收 ,起到关闭文件这样的作用,此时就会完成四次挥手过程,由于TCP连接的生命周期会比进程更长一些,因此可以完成四次挥手,与正常情况基本没什么区别

  2. 发送方或者接收方正常关机

    当有个主机进行关机时,操作系统就会强制终止所有的进程(类似上述的强杀进程过程),自然就会触发四次挥手,但是此时由于很快就要关机,因此四次握手不一定会全部完成,但是大概率第一个FIN报文能够发送给对端,此时对端也会回复ACK报文以及FIN报文,但是这些报文都不会再收到ACK了,此时对端就会触发超时重传,当重传几次仍然没有ACK后就会 单方面释放连接

  3. 发送方或者接收方断电关机

    如果直接断电,那么肯定是来不及发送第一个FIN报文的,此时就要考虑断电的是发送方还是接收方了

    1. 断电的是接收方:此时发送方就会发现,发送的数据没有ACK了,此时就会触发超时重传,重传多次仍没有ACK后就会尝试置RST位为1表示复位重置连接(消除原来的临时数据),但是RST也不会出现ACK报文,此时就单方面释放TCP连接了
    2. 断电的是发送方:此时接收方等待长时间没有收到来自发送方的数据时,就会周期性的发送"心跳"探测报文(不携带应用层数据),如果对端没有"心跳"那么就会单方面释放连接
  4. 网线断开

    相当于3中的a、b进行结合了,这里不再赘述!

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

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

相关文章

深入分析Java线程池——ThreadPoolExecutor

文章目录 Java 线程池概述ThreadPoolExecutor 构造方法线程池拒绝策略工作流程并发库中的线程池CachedThreadPoolFixedThreadPoolSingleThreadExecutorScheduledThreadPool ThreadPoolExecutor 源码分析线程池状态表示获取 runState获取 workerCount生成 ctl 提交任务 execute(…

漫谈技术成长

引言 相信很多程序员在自己的技术成长之路上,总会遇到许许多多的难关,有些难关咬咬牙就过去了,而有点难关则需要有一定的能力,才能克服。因此,本文主要围绕“技术成长” 话题,为何会选择技术方向&#xff0…

开源的Java图片处理库介绍

在 Java 生态系统中,有几个流行的开源库可以用于图片处理。这些库提供了丰富的功能,如图像缩放、裁剪、颜色调整、格式转换等。以下是几个常用的 Java 图片处理库的介绍,包括它们的核心类、主要作用和应用场景,以及一些简单的例子…

Normalizer(归一化)和MinMaxScaler(最小-最大标准化)的区别详解

1.Normalizer(归一化)(更加推荐使用) 优点:将每个样本向量的欧几里德长度缩放为1,适用于计算样本之间的相似性。 缺点:只对每个样本的特征进行缩放,不保留原始数据的分布形状。 公式…

C语言指针从入门到基础详解(非常详细)

1.内存和地址 我们知道电脑中的CPU在处理数据的时候需要在内存中读取数据处理后的数据也会放在内存中。把内存划分为一个个的内存单元每个单元的大小是一个字节。每个字节都有它对应的编号也就是它的地址,以便CPU可以快速的找到一个内存空间。C语言中我们把地址叫做…

MySQL-锁:共享锁(读)、排他锁(写)、表锁、行锁、意向锁、间隙锁,锁升级

MySQL-锁:共享锁(读)、排他锁(写)、表锁、行锁、意向锁、间隙锁 共享锁(读锁)、排他锁表锁行锁意向锁间隙锁锁升级 MySQL数据库中的锁是控制并发访问的重要机制,它们确保数据的一致性…

SQL中常见的DDL操作及示例,数据库操作及表操作

目录 一、数据库操作 1、创建数据库 2、查看所有数据库 3、使用数据库 4、删除数据库 二、表操作: 1、创建表 2、查看表结构 3、修改表结构 3.1 添加列 3.2 修改列数据类型 3.3 修改列名 3.4 删除列 3.5 修改表名 3.6 删除表 注意: 在数…

数字化解决方案的设计与实现:提升业务效率与用户体验

摘要:随着数字化时代的到来,越来越多的企业和组织开始寻求数字化解决方案来提升业务效率和改善用户体验。本文将探讨数字化解决方案的设计与实现过程,并介绍一些关键的技术和策略。 ## 引言 在当今竞争激烈的商业环境中,企业和组…

Unity 轮转图, 惯性, 自动回正, 点击选择

简单的实现 2D 以及 3D 的轮转图, 类似于 Web 中无限循环的轮播图那样. 文中所有代码均已同步至 github.com/SlimeNull/UnityTests 3D 轮转图: Assets/Scripts/Scenes/CarouselTestScene/Carousel.cs2D 轮转图: Assets/Scripts/Scenes/CarouselTestScene/UICarousel.cs 主要逻…

HashMap的底层实现

1、1.7版本的底层实现 HashMap在1.7版本中数据结构是数组链表, 1.1 put方法 put方法中操作步骤: (1)、对key计算相应的hash值,然后通过hash & table.length-1计算可以获得到在hash表中中相应的桶位置&#xff…

海外媒体宣发套餐如何利用3种方式洞察市场-华媒舍

在当今数字化时代,媒体宣发成为了企业推广产品和品牌的重要手段之一。其中,7FT媒体宣发套餐是一种常用而有效的宣传方式。本文将介绍这种媒体宣发套餐,以及如何利用它来洞察市场。 一、关键概念 在深入讨论7FT媒体宣发套餐之前,让…

golang实现正向代理和反向代理

文章目录 正向代理反向代理区别与联系:总结代理服务器实现正向代理反向代理正向代理 正向代理是客户端代理,它位于客户端和目标服务器之间。它的作用是保护客户端的隐私和安全。 如我们现在想要访问谷歌,但是由于某些原因,无法直接访问到谷歌,我们可以通过连接一台代理服务…

STM32_3-1点亮LED灯与蜂鸣器发声

STM32之GPIO GPIO在输出模式时可以控制端口输出高低电平,用以驱动Led蜂鸣器等外设,以及模拟通信协议输出时序等。 输入模式时可以读取端口的高低电平或电压,用于读取按键输入,外接模块电平信号输入,ADC电压采集灯 GP…

【NERF】入门学习整理(二)

【NERF】入门学习整理(二) 1. Hierarchicalsampling分层采样2. Loss定义(其实就是简单的均方差MSE)3. 隐式重建与显示重建1. Hierarchicalsampling分层采样 粗网络coarse,均匀采样64个点 缺点:如果仅使用粗网络会存在点位浪费和欠采样的问题,比比如空气中很多无效的点 精细…

【C语言】文件操作篇-----程序文件和数据文件,文件的打开和关闭,二进制文件和文本文件,fopen,fclose【图文详解】

欢迎来CILMY23的博客喔,本篇为【C语言】文件操作篇-----程序文件和数据文件,文件的打开和关闭,二进制文件和文本文件【图文详解】,感谢观看,支持的可以给个一键三连,点赞关注收藏。 前言 在了解完动态内存管…

运维随录实战(13)之docker搭建mysql集群(pxc)

了解 MySQL 集群之前,先看看单节点数据库的弊病 大型互联网程序用户群体庞大,所以架构需要特殊设计。单节点数据库无法满足大并发时性能上的要求。单节点的数据库没有冗余设计,无法满足高可用。单节点 MySQL无法承载巨大的业务量,数据库负载巨大常见 MySQL 集群方案 Re…

少儿编程 蓝桥杯青少组科技素养题 信息素养真题及解析第25套

少儿编程 科技素养 信息素养真题第25套 1、旅行结束之后,回到家的小蓝决定将照片备份在云端的网盘上。备份照片主要占用的是小蓝家的( )带宽 A、下行 B、上行 C、文件 D、数据 答案:B 考点分析:主要考查网络相关知识,要将照…

DHCP中继实验(华为)

思科设备参考: 一,技术简介 DHCP中继,可以实现在不同子网和物理网段之间处理和转发DHCP信息的功能。如果DHCP客户机与DHCP服务器在同一个物理网段,则客户机可以正确地获得动态分配的IP地址。如果不在同一个物理网段,…

JVM知识整体学习

前言:本篇没有任何建设性的想法,只是我很早之前在学JVM时记录的笔记,只是想从个人网站迁移过来。文章其实就是对《深入理解JVM虚拟机》的提炼,纯基础知识,网上一搜一大堆。 一、知识点脑图 本文只谈论HotSpots虚拟机。…

C# 视频转图片

在 C# 中将视频转换为图像可以使用 FFmpeg 库。下面是一个示例代码来完成这个任务: using System; using System.Diagnostics;class Program {static void Main(string[] args){string inputFile "input_video.mp4"; // 输入的视频文件路径string outpu…