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

核心机制:面向字节流

面向字节流

        读取/写入的时候,读写操作有很多方式,非常灵活

        读 100 字节

        1.一次读 10个字节,10次完成

        2.一次读 20 个字节,5次完成

        3.一次读 50 个字节,2次完成

粘包问题

接收方分用的时候,去掉报头,把载荷内容放到一个,接受缓冲区中

接受方的应用程序,read 的时候,就有很多种 read 的可能性

read 的可能性:

1)a   a   a   b   b   b   c   c   c

2)aa   ab  bb  cc  c

3)aaa   bbb   ccc

4)aaab   bbbc   c

5) aa   abb   bcc  c

怎么 read 是取决于应用程序的代码是咋写的

具体怎么来读,才能确保读到的是一个"完整的应用层数据包"

粘包,粘的是应用层的数据包

TCP 字节的特效,收到多个 TCP 数据报的时候把所有的载荷都给混到一起,放到接受缓冲区里

包的边界比较模糊,就好像是"粘上了一样"

粘包问题就是咱们非常需要关心的问题

1.通过特殊的分隔符,来作为包边界的区分

        比如, 约定每个应用层数据包,都已 ; 结尾

        包的数据里面,不能包含分隔符,需要找到合适的符号,确保这个符号在正文中不会重复出现,即使 ascil 码表中,也有不少的字符,可以用来作为分隔符的,有一下特殊的"不可见字符"历史遗留问题

在比如,之前写的回显服务器,当时是使用 \n 作为分隔符的

String request = sacnner.next(); => 读到空白符就结束了,空白符是统称,包括但是不限于:空格,换行,回车,制表符,分页符,垂直制表符

writer.println(request) => 发送请求的时候,使用 \n 作为结束标记的,由于是通过控制台来进行控制输入的请求内容的,控制台输入的内容本来就不会包含 \n

2.在应用层数据包开头的地方,通过固定长度,约定整个应用层数据包的长度

应用程序, read 的时候,先固定 read 2个字节,看看 2 个字节里面的内容是啥 => 发现是3接下来再 read 3 个字节,读到的 aaa 就是完整的应用层数据包

粘包问题只是针对字节流的传输.对于文件的操作,(使用文件存储多个结构性数据,也是可能涉及到粘包问题的)

比如,通过文件,保存若干个 学生信息

class Student {

        name

        id

        age

}

比如约定成,每个学生信息占一行(使用 \n 作为结束标记,作为分隔符)

对于 UDP 来说不存在粘包问题 UDP 的接受缓冲区和 TCP 的不太一样

应用层不需要做区分,应用层每次调用 recv 得到的就是一个完整的 DatagramPackage 也就对应一个完整的 应用层数据包

核心机制 异常情况

1.进程崩溃 [正常流程]

进程崩溃,意味着对应的文件描述符就被关闭了(调用 close,干掉进程) 只要是进程退出,都会释放 PCB,释放文件描述符表 触发 FIN

TCP 的连接并没有因为进程的结束立即结束,保留一会

2.主机关机 [正常流程]

正常流程下的主机关机,就会先杀死所有的进程,此时也会触发 FIN, 进而进入四次挥手,有可能挥不完

如果关机的速度比较慢,有很大可能四次挥手就挥完了

如果关机的速度比较快,刚发 FIN,机器就关了

对端可以正常返回 ack ,也会继续正常发送 FIN,这里的 FIN 就没有收到 ack,尝试几次重传 FIN 还是没有 ack,对端就直接放弃连接(删除之前保存的对端信息)

四次挥手,如果挥完了,双方可以确认,双发都能顺利吧保存的信息删掉

如果挥不完,至少直接可以把保存的信息删除掉,对端的就不管了

此时对端关机了,内存的数据全没了

3.主机掉电(直接拔电源)

直接啥都没了.来不及 FIN

1)如果掉电的一方是接受方,对方是发送方

对方继续发送数据,没有 ack =>超时重传 =>仍然没有 ack => 继续超时重传,达到一定的程度,掉电方仍然没有 ack ,发送方发送一个 复位报文,就是表示要重置连接放弃当前的连接

2)如果掉电的一方是发送方,对方是接受方

接受方感受到的是,发送方突然停下来了,接受方会继续阻塞等待,等待发送方发来新的数据(心跳包)

心跳包

接受方会周期性的和发送方交换"心跳包"

        A 给 B 发一个无业务数据的报文

        B 给 A 返回一个 ack

如果对方有应答,就可以认为对方是正常工作的

如果心跳包也没有应答,就可以认为,对方挂了

发现心跳包没有,就可以单方面的释放连接了(这个机制非常重要,尤其是分布式系统中,分布式系统中,知道,某个节点存活,非常重要)

TCP 协议自身虽然提供了心跳,心跳周期比较长,而在实际开发中,需要更高频的心跳应用层,代码实现的

4.网线断开

        本质上是和主机掉电是一样的.

        网线断卡的两端,一个是发送方,一个是接受方

                对于发送方来说,没有 ack => 超时重传 => 仍然没有 ack => 超时重传 => 达到一定程度放弃连接

对于接受方来说,周期性触发心跳包 => 发现对端下线 => 放弃连接

1.确认应答

2.超时重传

3.连接管理(三次握手,四次挥手)

4.滑动窗口(快速重传)

5.流量控制

6.拥塞控制

7.延时应答

8.捎带应答

9.面向字节流(粘包关系)

10.异常情况(心跳包)

这只是 TCP 协议的十大核心机制,TCP 还有其他机制

URG :表示"紧急指针"有效,正常情况下,TCP 的数据都是"顺序传输" 1- 1000, 1001- 2000,...., 紧急指针意味着后面有一些数据要先传输(插队),紧急指针的值表示,从当前位置往后多少个字节位置的部分,要进行插队的(使用比较少)

ACK: 应答报文

PSH:崔楚对方,尽快把缓冲区的数据交给应用程序

RST:复位报文

SYN:同步报文

FIN:结束报文

相关文章:

  • 业务:资产管理功能
  • Vim 调用外部命令学习笔记
  • 新一代 Rust Web 框架的高性能之选
  • 【数据结构】图算法(代码)
  • 微信小程序中的计算属性库-miniprogram-computed
  • 全新AI驱动Workspace Security 套件发布!Fortinet 电子邮件安全产品矩阵升级
  • docker compose v2版本创建和运行容器
  • 第九章 窗口看门狗(WWDG)
  • 在 macOS 上搭建 Flutter 开发环境
  • 论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(四)
  • 企业产品网络安全日志6月10日-WAF资费消耗排查
  • 【FFmpeg学习(2)】视频概念
  • 【FFmpeg学习(1)】图像表示
  • 如何将数据从 iPhone 传输到笔记本电脑
  • HTML盒子模型
  • 《网络世界的“隐形窥探者”:深度剖析网络监听》
  • SCAU期末笔记 - 数据分析与数据挖掘题库解析
  • 基于GeoTools求解GeoTIFF的最大最小值方法
  • AI时代,数据分析师如何成为不可替代的个体
  • 访问服务器项目,服务器可以ping通,但是端口访问不到
  • 扁平化网站模板下载/培训机构加盟
  • 南宁市住房和城乡建设局/seo怎么优化方案
  • 做网站视频赚钱吗/最吸引人的引流话术
  • 属于免费推广的方式是/网络关键词优化方法
  • 建立相适应的政府债务管理机制/seo快速排名是什么
  • 家政网站建设/成年学校培训班