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

【JavaEE初阶】网络原理(3)

欢迎关注个人主页:逸狼


创造不易,可以点点赞吗~

如有错误,欢迎指出~



目录

TCP的核心机制四=>滑动窗口

遇到丢包如何解决

TCP的核心机制五=>流量控制

设置窗口大小 

TCP核心机制六=>拥塞控制

TCP核心机制七=>延时应答

TCP核心机制八=>捎带应答

TCP核心机制九=>面向字节流

粘包问题

解决粘包问题

方案1:指定分隔符

方案2:指定数据的长度

TCP核心机制十=>异常情况处理

1.进程崩溃

2.主机关机(正常流程关机)

3.主机掉电(拔电源)

接收方掉电

发送方掉电

4.网线断开

TCP和UDP使用场景对比


接着上一篇我们继续谈TCP的核心机制~

TCP的核心机制四=>滑动窗口

可靠传输的代价是 降低了传输的效率,TCP希望能够在可靠传输的基础上也有一个不错的效率,所以引入了滑动窗口.

改进方案:把"发送一个等待一个"改成"发送一批等待一批",把多次等待ack的时间合并成一份时间,批量发送的数据越多,此时效率就可以认为是越高

批量发送的数据,不需要等待的数据量 称为"窗口大小"

遇到丢包如何解决

针对情况1,不需要任何处理

批量发数据,批量ACK,多个ACK只是丢了一部分,不可能全丢

虽然1001ack丢了,但2001到达了,发送方收到2001之后,意味着2001之前的数据都已经收到了(后一个ack能够涵盖前一个ack的意义)

针对情况2:快速识别出哪个数据包丢失,并且针对性的重传,其他顺利到达的数据都无需重传.这个过程称为"快速重传"

B收到的数据1-1000 和2001-3000,其中1001-2000这个数据丢失,此时B收到2001-3000时返回的ack确认序号是1001,而不是3001(B在向A索要1001的数据),接下来B收到的3001-4000,4001-5000,....对应的ack确认序号都是1001 ,A 收到多个1001这样的ack后就意识到1001数据包丢失,A于是就重传1001-2000 

TCP的核心机制五=>流量控制

滑动窗口的窗口大小对于传输数据的性能是直接相关的,但是窗口能无限大吗?

通信是双方的事情,发送方发的快了,也要确保接收方可以处理得过来

这里需要让接收方的处理能力 反向制约 发送方的发送速度,这就是 流量控制

设置窗口大小 

如果发送的速度特别,消费数据比较,就会使接收缓冲区装满,此时,如果发送方强行发数据,就会丢包(被接收方丢弃了)

Linux内核里,就是用"水位"这个词来表示接收缓冲区中有多少数据的

  • 如果空闲空间越大,就可以认为,是应用程序处理的速度比较,就可以让发送方 发快一点,设置一个更大的窗口大小
  • 如果空闲空间越,就可以认为,是应用程序处理的速度比较慢,就可以让发送方 发慢一点,设置一个更小的窗口大小'

TCP中,接收方收到数据时,就会把接收缓冲区剩余空间大小通过ACK数据报 反馈给发送方,下一步,发送方就可以依据这个数据来设置发送的窗口大小

"16位窗口大小" 中的16位表示的范围是64KB,是否意味着发送方窗口大小最大就是64KB?

 其中"选项"中可以设置一个特殊选项"窗口扩展因子"

计算公式:  发送方的窗口大小 = 窗口大小 << 窗口扩展因子

其中的 "<<" 表示左移运算(左移1位,表示 "乘2")

流量控制 也不是TCP独有的机制,其他协议也可能会涉及的流量控制(如 数据链路层中有的协议,也支持流量控制)

TCP核心机制六=>拥塞控制

拥塞控制与流量控制相关联,它们都是在对于"可靠传输"进行补充

  • 流量控制:站在接收方的视角来限制发送方的速度
  • 拥塞控制:站在传输链路层的视角来限制发送方的速度

传输链路中的中间节点情况非常复杂(中间节点非常多;每次走的路线还不一定一样;中间哪个节点出现问题也不好说;可能还有其他设备传输数据经过某个中间节点)

可以通过"做实验"的方式 来找到合适的发送速度

  1. 先按照一个比较的速度发送数据
  2. 若数据非常畅通,没有丢包,说明网络上传输数据整体是比较通畅的=>加快传输速度
  3. 到达一定速度,发现丢包,说明网络上可能存在拥堵 => 减慢传输速度
  4. 减速后,发现不丢包,再加速;....

一直持续动态变化~

流量控制和拥塞控制共同起作用 限制了发送窗口大小,最终实际窗口大小取决于这两个机制得到的发送窗口的 较小值

TCP核心机制七=>延时应答

延时应答用于尽可能 降低可靠传输带来的性能影响(提升性能 =>让滑动窗口变大)

在接收方收到数据后 让ack不是立即返回,在晚一点的时间内,应用程序就有机会,读取到缓冲区中更多的数据,进而消费掉更多的数据.在延时返回的ack的窗口大小,大概率要比立即返回的ack的窗口更大

假设让ack不是立即返回,而是100ms之后返回,此时在100ms之内,应用程序可能又消费掉了2kb的数据,此时返回ack携带的窗口大小就是6kb

TCP核心机制八=>捎带应答

捎带应答 是把返回的业务数据和ack 两者合二为一了, 在延时应答基础上,引入的提升效率的机制

正常情况下,ack和响应 是不同的时机 ,无法合并,但是ack涉及到了"延时应答",会使ack返回的时间被往后拖,这里的延时可能赶上 接下来发送响应数据的操作了,于是就可以在发送响应时把刚才的ack的信息也带上

ack和响应 可以共存

  • ack报文不需要载荷,报头中设置ack这一位为1,窗口大小的值,确认序号...
  • 响应数据主要设置的是 载荷

TCP核心机制九=>面向字节流

粘包问题

通过面向字节流的方式传输数据都会涉及到"粘包问题",TCP中粘的是"携带的载荷"(应用层数据包)

应用层数据包在TCP的 接受缓冲区中 连成一片黏在一起就称为"粘包问题"

上图中 aaa,bbb,ccc才是完整的"应用层数据包"

解决粘包问题

关键在于明确"包和包之间的边界"

方案1:指定分隔符

适用于文本类的数据,比如约定请求和响应都以 \n结尾.

方案2:指定数据的长度

约定在每个应用层数据包 的开头2或4个字节表示数据包的长度(如果是传输二进制数据,这个方案就很有用了)

TCP核心机制十=>异常情况处理

1.进程崩溃

Java中的体现就是抛出异常,但是没人catch时,最终异常到了jvm这里,jvm进程会直接挂掉

看起来是"崩溃",实际上操作系统会进行"善后"(当进程崩溃时,进程中的PCB就要被回收,PCB中的文件描述符表里对应的所有文件,也会被系统自动关闭,其中针对socket文件,也会触发正常的关闭流程(TCP四次挥手))

2.主机关机(正常流程关机)

正常流程点击关机按钮,此时操作系统就会先干掉所有的进程,同时会触发四次挥手

  • 四次挥手非常快,四次挥手在关机动作之前完成
  • 四次挥手没来得及挥完,关机就完成了

3.主机掉电(拔电源)

接收方掉电

A给B发送数据,B不会再有ACK回应了

A会触发超时重传,重传的数据当然还是没有响应,

反复多次之后,A尝试重置连接(rst)

重置操作也没有ack,A就会单方面释放连接(A把 保存的B的信息删除掉)

发送方掉电

A发着发着不发了,B的视角看来,不知道A是挂了,还是晚点再发.

此时B就会给A发送一个数据包(探测报文=>不携带业务数据,只是为了触发ACK)

  • 如果A返回了ACK,说明A没有挂
  • 如果A没有ACK,甚至连续多个探测报文都没有ACK,就可以视为A已经挂了

这个用来探测对方的"生死"的报文称为"心跳包",有周期性的.

TCP内置了心跳包,由于它的周期比较长(秒级-分级)应用程序这一层通常会自行实现一些心跳包,达到更快速的"保活机制"

4.网线断开

和主机掉电是一样的,是两者的复合体

TCP和UDP使用场景对比

TCP和UDP这两个协议并无优劣之分,他们在不同的场景发挥作用

  • TCP对于数据需要可靠传输的场景必然是 首选
  • UDP对于可靠性要求不高,对于性能要求很高的场景=>分布式系统中,主机之间的通信

http://www.kler.cn/news/366532.html

相关文章:

  • CLion远程开发Ubuntu,并显示helloworld文字框
  • kubeadm快速自动化部署k8s集群
  • 【Qt聊天室客户端】聊天界面功能
  • 基于vue框架的的高校消防设施管理系统06y99(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • WPF的UpdateSourceTrigger属性
  • VS code部署Vue项目Demo
  • SwiftUI 中 List 或 Form 子视图关联的 swipeAction 导致展开动画异常的解决
  • JVM学习总结:字节码篇
  • ElasticSearch-7.17.24设置密码及CA证书
  • Anthropic推出Claude 3.5 Sonnet模型 性能超越GPT-4o和Gemini 1.5 Pro
  • 【前端】css样式
  • 基于neo4j的旅游知识图谱维护与问答系统
  • cnn_lstm_kan模型创新实现股票预测
  • 2024年10月25日第三部分
  • 【C++篇】深度解析类与对象(下)
  • Java爬虫:API数据界的“宝藏猎人”
  • Linux Java 多版本管理
  • 2024 年让这4个在线翻译器成为你语言沟通的得力助手。
  • 如何确保WordPress网站数据安全:定期备份与恢复
  • untiy中使用StackExchange.Redis读取Redis
  • python爬虫百度图片
  • 第五届无线大数据研讨会 日程表
  • 3. IoC 与DI
  • python如何读取Excel文件!
  • 使用virtualenv/Anaconda/Miniconda创建python虚拟环境
  • 实战分享:Golang中实现高性能日志记录与错误跟踪的艺术