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

【JavaSE】【网络原理】UDP和TCP原理

目录

  • 一、UDP协议
  • 二、TCP协议
    • 2.1 TCP结构
    • 2.2 TCP十大核心机制
      • 2.2.1 确认应答
      • 2.2.2 超时重传
      • 2.2.3 连接管理
        • 2.2.3.1 三次握手建立连接
        • 2.2.3.2 四次挥手断开连接
      • 2.2.4 滑动窗口
      • 2.2.5 流量控制
      • 2.2.6 拥塞控制
      • 2.2.7 延时应答
      • 2.2.8 捎带应答
      • 2.2.9 面向字节流
      • 2.2.10 异常情况处理
  • 三、TCP、UDP对比

一、UDP协议

UDP在前面套接字编程介绍了特点是:
无连接、不可靠传输、面向数据报、全双工。

UDP协议格式:

  • 16位UDP⻓度,表⽰整个数据报 (UDP⾸部+UDP数据) 的最⼤⻓度,0 - 65535,也就64KB;
  • 16位UDP校验和:如果校验和出错,就会直接丢弃;

校验和的作用:

  • 防止传输过程出现比特翻转(比特翻转就是指:数据受到外界干扰,0变1,1变0)

发送之前,先计算一个校验和,把真个数据报的数据都代入
把数据 和 校验和 一起发送给对端
接收方收到之后重新计算一下校验和,和收到的校验和进行对比(UDP发现校验和不一致,就会直接丢弃)
UDP的校验和使用了CRC方式来进行校验(循环冗余校验)
把每个字节(除了校验和位置的部分之外),都当做整数进行累加.溢出也没关系,继续加
最终得到结果CRC校验和
传输到对端时,数据如果出现错误了,对端再次计算的校验和,就会和第一个校验和不一样了
校验和相同,原始数据可能相同(原始数据不同发生的概率非常小)。
校验和不同,原始数据一定不同。

这样的机制虽然也有错,因为一个数据和对应的数据不是唯一的,但是这种是小概率事件。

二、TCP协议

2.1 TCP结构

TCP在前面套接字编程介绍了特点是:
有连接、可靠传输、面向字节流、全双工。

TCP格式:

  • 4位首部长度:表⽰该TCP头部有多少个32位bit (有多少个4字节);所以TCP头部最⼤⻓度是15 * 4 = 60 字节
  • 选项:选项就是确定TCP长度是可变的,固定长度是20字节,选项最多增加40字节
  • 保留位:UDP长度不够时,不能扩展,而保留位就是TCP预留解决这种问题的。
  • 6个标志位:
    • URG:紧急指针(相当于“插队”,跳过前面数据,从指定序号开始)是否有效
    • ACK:确认号是否有效
    • PSH:催促标志位,提⽰接收端应⽤程序⽴刻从TCP缓冲区把数据读⾛
    • PST:对⽅要求重新建⽴连接;我们把携带RST标识的称为复位报⽂段
    • SYN:请求建⽴连接;我们把携带SYN标识的称为同步报⽂段
    • FIN:通知对⽅,本端要关闭了,我们称携带FIN标识的为结束报⽂段
  • 16位校验和:校验数据是否出现错误
  • 16位紧急指针:标识哪部分数据是紧急数据

2.2 TCP十大核心机制

2.2.1 确认应答

保证可靠性:那就肯定需要,发送放知道接收方是否接收到请求,接收方返回一个“应答报文(acknowledge ,ack)”

如果有这种情况:后发先至

网上做题是答案是对应题目的,但是如果你先写的第一题答案,后写的第二题答案,由于传输问题,导致第二题答案先到。那么如果没有题号对应的话,那么就可能填在第一题去了。所以TCP也引入的类似题号作用的东西:序列号

TCP将每个字节的数据都进⾏了编号。即为序列号。
每⼀个ACK都带有对应的确认序列号,意思是告诉发送者,该确认序号前的数据都已经收到;下⼀次你从哪⾥开始发。

2.2.2 超时重传

超时重传是为了应对丢包问题。

丢包:数据无法到达指定位置。

丢包两个原因:假如主机A发送数据给主机B

  1. 主机A发送的数据,由于各种原因,没能到达主机B,造成丢包
  2. 主句B返回的应答数据,由于各种原因,没能到达主机A,造成丢包

TCP就引入超时时间(TCP中判定超时的时间阈值,不是固定值,动态变化),来应对丢包情况,
当超出超时时间,还没有接收到应答报文,那么就是出现丢包(无论哪种原因造成),那么都会重新发送这条数据。

超时时间的动态变化机制:

TCP为了保证⽆论在任何环境下都能⽐较⾼性能的通信,因此会动态计算这个最⼤超时时间。

  • Linux中(BSD Unix和Windows也是如此),超时以500ms为⼀个单位进⾏控制, 每次判定超时重发的
    超时时间都是500ms的整数倍.
  • 如果重发⼀次之后, 仍然得不到应答, 等待 2*500ms 后再进⾏重传.
  • 如果仍然得不到应答, 等待 4*500ms 进⾏重传. 依次类推, 以指数形式递增.
  • 累计到⼀定的重传次数, TCP认为⽹络或者对端主机出现异常, 强制关闭连接.

确认应答和超时重传是确认TCP可靠传输的最核心机制

2.2.3 连接管理

TCP中连接是逻辑上的连接,都保留对端的信息,不是物理上的连接。

两个主机间的连接管理,TCP通过三次握手机制建立连接,四次挥手断开连接。

2.2.3.1 三次握手建立连接

过程简述:主机A与主机B通信

  1. 主机A先发一个状态码为syn的报文给主机B(相当于我给你打电话,你接通后,我先说一个喂)
  2. 主机B接收到主机A发的报文后,也要发一个状态码为ack的应答报文,还要发送一个syn报文,这两个报文可以一起发送。(这就相当于打电话,你听到了我说喂,你回一个干嘛)
  3. 主机A收到主机B的报文后,要发送一个状态码为ack的应答报文。(就相当于打电话,我知道你那边听筒和麦克风正常,我就开始说事了,你听到我说事,也就知道我设备没问题,但是在TCP中要应答报文,让主机B知道,然后才是发送数据)

syn和ack报文简述:

  1. syn报文,就是通知对端我要和你建立连接了,这里面包含了发送端的信息,让对端保存好
  2. ack报文,就是通知对端你发的报文,我收到了,将信息记录好了。

三次握手简图:

三次握手机制好处:

  1. 三次握手,相当于“投石问路”,初步探索一下网络通信链路是不是畅通的
  2. 验证通信双方的发送和接收能力是不是正常的。
  3. 三次握手过程中,是可以协商一些关键数据的,比如通信的初始序号
2.2.3.2 四次挥手断开连接

过程简述:主机A与主机B通信

  1. 主机A先发一个状态码为FIN的报文给主机B(相当于我给你打电话,我要挂电话了,我说我要挂电话了,你还有事吗)
  2. 主机B接收到主机A发的报文后,也要发一个状态码为ack的应答报文,(这就相当于打电话,你听到了我说要挂电话了)
  3. 还要发送一个FIN报文。(这就相当于打电话,你听到了我说要挂电话了,你回一个ok)
  4. 主机A收到主机B的报文后,要发送一个状态码为ack的应答报文。(就相当于打电话,我挂电话)

在四次挥手时:接收端发送的FIN和ACK报文如能合并。

接收端发送的FIN和ACK报文,只有在延时应答机制下才能合并。而其他时候不能合并。因为ACK的报文是操作系统内核发的,而FIN报文是程序猿代码调用到Socket的close方法才发送的。

四次握手简图:

三次握手与四次挥手的丢包问题:

三次握手无论哪个报文发生丢包,触发超时重传就可以解决。
四次挥手中在除了最后发送端(主机A)的ACK报文外,其它报文发生丢包问题,触发超时重传就可以解决。
当发送端(主机A)接收到了FIN,直接发送ACK,同时释放这次资源,那么如果ACK丢包,主机B重传FIN后,主机A都不认识了。这是就引入一个TIME-WAIT状态(在接收到了FIN后等一定时间),再释放资源。

CLOSE-WAIT:

⼀般⽽⾔,对于服务器上出现⼤量的 CLOSE_WAIT 状态, 原因就是服务器没有正确的关闭 socket, 导致四次挥⼿没有正确完成. 这是⼀个 BUG. 只需要加上对应的 close 即可解决问题.

三次握手和四次挥手的详图(出自《图解TCP/IP》)

2.2.4 滑动窗口

滑动窗口:

像在发送数据报的时候,我们发一条等待对方接收一条返回一条应答报文,那么和发一堆再进入等待状态相比,明显后者的效率更高。
滑动窗口就是指第二种发数据方式。

滑动窗口机制解析:

  • 窗口大小:就是指无需等待的数据报数量,也就是第一次可以发送的最大值。
  • 进出数据:滑动窗口中的数据,接收到了哪个确认序列号,就将滑动窗口的头移动到对应的确认序列号的数据地方
  • 操作系统内核为了维护这个滑动窗⼝, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只有确认应答过的数据, 才能从缓冲区删掉;
  • 滑动窗口的大小要适量,过大会影响TCP的可靠性,过小对效率提升没啥作用。

滑动窗口中的丢包问题:

  1. 数据报已经抵达, ACK丢了。
    这种情况,不用任何处理,因为后面到达的ACK的确认序号就包含了,前面的数据都接收到了的意思。

  2. 数据报丢了
    快速重传:在滑动窗口下的变种机制。
    2.1. 当某⼀段报⽂段丢失之后, 发送端会⼀直收到 1001 这样的ACK, 就像是在提醒发送端 “我想要的是1001” ⼀样;
    2.2. 如果发送端主机连续多次都收到了同样⼀个 “1001” 这样的应答, 就会将对应的数据 1001 - 2000 重新发送;
    2.3. 这个时候接收端收到了 1001 之后, 再次返回的ACK就是7001了(因为2001 - 7000)接收端其实之前就
    已经收到了, 被放到了接收端操作系统内核的接收缓冲区中;

2.2.5 流量控制

流量控制:

接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满(就像小学数学小明给泳池一边放水一边蓄水一样), 这个时候如果发送端继续发送, 就会造成丢包, 继⽽引起丢包重传等等⼀系列连锁反应.
因此TCP⽀持根据接收端的处理能⼒, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control);

如何实现流量控制:

  • 接收端将自己的接收缓冲区剩余的容量,通过TCP首部的“十六位窗口大小”字段,通过ACK发给发送端,发送端根据这个值来设置滑动窗口大小,来实现流量控制。

特点:

  • 16位数字最⼤表⽰65535,但是TCP窗⼝最⼤却不是65535字节么。实际上,TCP⾸部40字节选项中还包含了⼀个窗⼝扩⼤因⼦M,实际窗⼝⼤⼩是 窗⼝字段的值左移 M 位;
  • 如果接收端缓冲区满了,就会将窗⼝置为0;这时发送⽅不再发送数据,但是需要定期发送⼀个窗⼝探测数据段,使接收端把窗⼝⼤⼩告诉发送端。

流程解释图:

2.2.6 拥塞控制

拥塞控制:依据通信链路的转发能力,进行限制。

找拥塞控制的滑动窗口的大小:

我们前面的流量控制的滑动窗口的大小,直接是TCP首部字段带的。但是我们通信链路没这个功能,我们就将通信链路当一个整体,先按照小的窗口发着,一直加大窗口,当窗口过大,发生丢包就减小窗口到较小值,再次执行前面操作,又增大窗口(面多加水,水多加面),让窗口大小一直处于丢包临界值动态平衡。

图解:

  • 慢启动:初始的小窗口大小

  • ssthresh初始值:预设的窗口大小

  • 过程解析:慢启动 -> 指数增长 -> 线性增长 -> 丢包,窗口变回较小值

滑动窗口的最终大小取决于拥塞控制和流量控制的较小值

2.2.7 延时应答

延时应答:

默认情况,接收方收到数据报第一时间返回ACK,但是可以通过延时应答,延时返回ACK的方式提高效率。
返回窗口的大小跟流量控制,接收缓冲区剩余容量的大小有关,当接收到数据报的时候,等一会,程序就会消耗缓冲区的数据报,这样我们返回的ACK的窗口大小(剩余容量)就可以比不等直接返回的大,提高效率。

但是如果程序消耗的速度比不上发送方的发送速度,引入延时机制相反还会是窗口大小变小,降低效率。

延时应答限制:

  • 数量限制: 每隔N个包就应答⼀次;
  • 时间限制: 超过最⼤延迟时间就应答⼀次;

图解:

2.2.8 捎带应答

捎带应答:

引入了延时应答,接收方得到数据后,不会立刻返回当前数据报的ACK,那么下次返回数据的时候,捎带把上次的ACK带回去。

图解:

2.2.9 面向字节流

面向字节流:

创建⼀个TCP的socket, 同时在内核中创建⼀个 发送缓冲区 和⼀个 接收缓冲区;
• 调⽤write时, 数据会先写⼊发送缓冲区中;
• 如果发送的字节数太⻓, 会被拆分成多个TCP的数据包发出;
• 如果发送的字节数太短, 就会先在缓冲区⾥等待, 等到缓冲区⻓度差不多了, 或者其他合适的时机发
送出去;
• 接收数据的时候, 数据也是从⽹卡驱动程序到达内核的接收缓冲区;
• 然后应⽤程序可以调⽤read从接收缓冲区拿数据;
• 另⼀⽅⾯, TCP的⼀个连接, 既有发送缓冲区, 也有接收缓冲区, 那么对于这⼀个连接, 既可以读数据, 也可以写数据. 这个概念叫做 全双⼯
由于缓冲区的存在, TCP程序的读和写不需要⼀⼀匹配, 例如:
• 写100个字节数据时, 可以调⽤⼀次write写100个字节, 也可以调⽤100次write, 每次写⼀个字节;
• 读100个字节数据时, 也完全不需要考虑写的时候是怎么写的, 既可以⼀次read 100个字节, 也可以⼀
次read⼀个字节, 重复100次;

粘包问题:

  • 粘的是“应用层数据包”
  • 在TCP的协议头中, 没有如同UDP⼀样的 “报⽂⻓度” 这样的字段, 但是有⼀个序号这样的字段.
  • 站在传输层的⻆度, TCP是⼀个⼀个报⽂过来的. 按照序号排好序放在缓冲区中.
  • 站在应⽤层的⻆度, 看到的只是⼀串连续的字节数据.
  • 那么应⽤程序看到了这么⼀连串的字节数据, 就不知道从哪个部分开始到哪个部分, 是⼀个完整的应⽤层数据包.

解决方法:

  • 在TCP角度无解,在应用层解决。
  • 法1:约定包与包之间的分隔符(包的结束标志);
  • 法2:约定包的长度(例如固定开始几个字节表示接下来的数据包的长度)

2.2.10 异常情况处理

  • 进程终⽌:进程终⽌会释放⽂件描述符,仍然可以四次挥手发送FIN。和正常关闭没有什么区别。
  • 机器重启/正常关机:本质上还是先杀死所有进程,和进程终⽌的情况相同。
  • 接收端掉电:触发超时重传,触发“重置连接”,发送方方主动发送一个复位报文RST,还没回应就断开连接。
  • 发送方掉电:发送方一直不发,接收方等到一定时间,像发送方传输一个特殊报文“心跳包”,不携带数据,为了触发ACK,还是没有就断开连接。
  • ⽹线断开:就是相当于接收方和发送方同时掉电了。两边都进行操作。

三、TCP、UDP对比

TCP,UDP对⽐:

  • TCP是可靠连接,但是TCP不⼀定就优于UDP。TCP和UDP之间的优点和缺点,不能简单、绝对的进⾏⽐较
  • TCP⽤于可靠传输的情况,应⽤于⽂件传输,重要状态更新等场景;
  • UDP⽤于对⾼速传输和实时性要求较⾼的通信领域,例如,早期的QQ,视频传输等。另外UDP可以⽤于⼴播;
http://www.dtcms.com/a/395382.html

相关文章:

  • 高防IP真的能抵御DDoS攻击吗?
  • 93. 复原 IP 地址
  • 智能排班系统,促进人岗匹配提升人效
  • PostgreSQL介绍和PostgreSQL包安装
  • 分享“泰迪杯”数据挖掘挑战赛全新升级——赛题精准对标,搭建 “白名单” 赛事进阶通道
  • 对接文档:快递鸟取件码API,实现物流末端服务自动化
  • GIS学习:GIS认知与开发初步入门
  • 9. NVME与SSD之间的通信
  • Navicat连接PostgreSQL报错:authentication method 10 not supported
  • Diffusion 模型解读
  • 【寰宇光锥舟】 数学模型讨论
  • Further inference in the multiple linear regression model
  • Turtlebot: 开源机器人开发平台 SLAM硬件搭建(激光雷达+IMU+相机+移动底盘)
  • Java 线程的几种状态
  • 在线ps修改图片中的文字
  • Hadoop 保姆级搭建手册:突出教程的细致和易上手
  • 使用gsettings修改命令ubuntu快捷键
  • Linux线程互斥与同步
  • 【AI扣子生成测试用例】自动生成测试用例工作流
  • Hive建表实战
  • Ethernaut Level 5: Token - 整数下溢攻击详解
  • 正向代理 vs 反向代理
  • SNN论文阅读——spikformer
  • 【论文阅读】Robix:机器人交互、推理与规划的统一模型
  • 【论文阅读】AutoDrive-R^2: 激励自动驾驶VLA模型的推理与自我反思能力
  • [UnrealEngine] 虚幻引擎UE5下载及安装(UE4、UE5)
  • AI原生安全架构的提出与落地路径:来自南凌科技的实践观察
  • ELK企业级日志分析系统
  • EasyDSS一站式点播方案如何提升企业视频门户的用户体验?
  • MARSIM仿真平台部署安装及FUEL部署-Ubuntu20.04