深度挖掘《TCP与UDP》

news2024/12/23 8:25:17

文章目录

    • UDP
    • TCP
      • TCP特性
      • TCP是如何实现的可靠传输?
      • 序号和确认序号
      • 为啥网络上会后发先至
    • 什么是丢包,如何解决丢包?
      • TCP建立连接:三次握手
      • 四次交互,为什叫三次握手?
      • 三次握手起到什么效果?达到什么目标呢?
      • 四次握手行不行?
      • TCP断开连接:四次挥手
      • 为什么三次握手100%合并,四次挥手概率合并?
    • 滑动窗口(效率机制)
        • 批量发送的过程中,如果出现丢包咋办?
      • 流量控制
      • 拥塞控制
      • 延时等待
      • 捎带应答
      • 面向字节流---粘包问题
    • 关于异常情况
      • 进程关闭/进程崩溃
      • 主机关机(正常关闭)
      • 主机断电和网络断开
      • TCP和UDP的应用场景

UDP

UDP报文格式:报头(包含4个字段)+载核(应用层数据报)
在这里插入图片描述

源端口:数据从哪里来
目的端口:数据送到哪里去
报文长度:在传输数据时,单个报文段的最大长度
校验和:为保障数据正确性
注意:以上4个均为两字节,报文最大不能超过65536。

如果真的要传输一个数据量大的信息,UDP如何处理?

  1. 可以把大的数据分成多个部分,使用多个UDP数据报进行传输
  2. 直接使用TCP,TCP无限制

为什么要有校验和,没有行不行?
不行,首先校验和是为了保证数据的正确性,网络在传输时是不稳定的,传输使用的是电信号,电信号用0或1表示,当由于外界的影响导致电信号0->1或1->0是不可避免的。发送方把载核通过校验和算法计算出sum1,发送方把数据发送到接收方,当接受方收到数据时也采用相同的校验和算法计算出sum2,此时比较sum1和sum2的值是否相等判断数据发送的正确性。

TCP

在这里插入图片描述

TCP特性

  • 有连接
  • 可靠传输
  • 面向字节流
  • 全双工

TCP是如何实现的可靠传输?

TCP不是说,100%能够传过去,当传不过去的时候发送方知道自己没传过去,也就是说在接受方,收到或者没收到,会有个应答,此机制称为确认应答(ACK),实现可靠性的最核心机制!
一切顺利:使用确认应答保证可靠性
出现丢包,使用超时重传作为补充

序号和确认序号

当发送消息时还会产生后发先到的情况,为解决此问题我们可以添加编号(序列号)方式来确认,此时就引入了序号和确认序号。TCP针对每个字节进行编号注意,确认序号的规则,不是说,发送方的序号是啥就是啥,而是取得是发送方发过来的所有数据,最后一个字节的下一个字节的序号作为确认序号。确认序号的含义:小于确认序号的数据,我已收到。此时发送方就能知道那些数据接收到了。

为啥网络上会后发先至

TCP在传输时,因为面向字节流传输,一条完整数据分成每部分,每个部分数据走的路径不一样就会导致后发先到,TCP有一个接收缓冲区,TCP可以按序号针对收到的消息进行整队(这也是TCP序号的一个重要用途)。此时应用程序读数据,读到的一定是有序的了(和发送顺序一样)。

什么是丢包,如何解决丢包?

比如你正在打游戏此时画面卡成ppt,也就是说在传输数据时丢失了。丢包是指在网络传输过程中,数据包因为各种原因没有正确地到达目标地点,而丢失的现象。
在传输数据时,利用交换机和路由器每个设备都在承担很多转发任务,每个设备的转发能力是有上限的,当某一时刻某个设备流量达到峰值此时会引起丢包。
如果包丢了,此时接受方就接收不到了,也就不会返回ACK,发送方就迟迟拿不到应答报文,此时等待一段时间还没收到,则认为是丢包。此时就会重新发一遍也称为“超时重传”。

发送方对于丢包的判定,一段时间内没有收到ACK

  1. 数据直接丢了,接收方没收到,自然不会发ACK
  2. 接收方发送了ACK,但是返回的ACK丢了

由于发送方区分不了这两种情况,所以只能都重传。
当是第二种情况数据重发是非常严重的,但是TCP非常好的处理了此问题,它会在接收缓冲区中根据收到的数据的序号,自动去重。保证应用程序读到的数据只有一份。重传后的数据也是会导致丢包的,一旦连续丢包这种情况很大的可能是网络出现了严重的问题。
TCP针对多个包丢失,每次丢包超时等待时间就会变长(重传的频率变低了),连连续多次重传,都无法得到ACK,此时TCP就会尝试重置连接,如果重置连接也失效,TCP就会关闭连接,放弃网络通信。

TCP建立连接:三次握手

syn:称为同步报文段,一方向另一方申请建立连接
ack:应答信号
在这里插入图片描述

四次交互,为什叫三次握手?

因为上图中间部分服务器向客户端发送的ack和syn可以合并成一个。
在这里插入图片描述

三次握手起到什么效果?达到什么目标呢?

三次握手这个过程,验证了客服端和服务器,个资的发送能力和接收能力是否正常,也为可靠性做出了一份力。

四次握手行不行?

可以,中间部分服务器向客户端发送的ack和syn可以分开成两个分别发送,也就是四次握手。但是效率低于三次握手。

TCP断开连接:四次挥手

通信双方,各自给对方发送一个FIN(结束报文),在各自给对方返回ACK。
在这里插入图片描述

为什么三次握手100%合并,四次挥手概率合并?

ACK和FIN有一定概率合并成一个,但通常情况下不能合并。
三次握手:ACK和SYN是同一时机触发的(都是由内核完成的)
四次挥手:ACK和FIN是不同时机触发,ACK是内核完成的,会在收到FIN的时候第一时间返回,FIN则是应用程序代码控制,再调用socket的close方法的时候才会触发FIN,close的执行时机可能是很久也可能是立即取决于代码怎么写。
客户端进程结束了,但是TCP还会把TCP连接维护,直到四次挥手结束。

滑动窗口(效率机制)

想要提高效率,减少等待时间,可以采用批量发送(一次发多条数据,收到一个ACK就可以直接发下一条数据)。批量不是无限发送,是发送到一定程度,就等待ack,不等待直接发送的数据量是有上限的,而且是回来一个ack就立即发送下一条,相当于总的要批量等待的数据是一致的(滑动窗口大小)。
在这里插入图片描述
在这里插入图片描述

批量发送了四条数据,就等待着四个ack,白色区域就是等待窗口,当收到2001的ack就意味着1001~2000的这个数据得到了确认,此时就会立即发送5001~6000这个数据。

批量发送的过程中,如果出现丢包咋办?

在这里插入图片描述

这个图中相当于一半的ack都丢了,相当高的丢包率,这种情况啥事没有,对于可靠性没有影响,因为通过后一个ack能告诉我们前面ack虽然是丢了但是我收到了。若是程序 最后一个数据的ack丢失我们采用超时重传。

在这里插入图片描述

由于1001~2000的数据丢了,但是接收方依然索要的是1001的数据,而不是收到了2001~3000的数据,返回3001。当A收到多个索要1001这个数据,1A就重传此数据,当B收到了1001~2000的数据,B的返回ACK确认序号是7001,因为之前的数据我已经收到了。上述重传过程,丢了数据才重传,不丢不重传,整体速度比较快,重传过程也称为快速重传
滑动窗口和快速重传,是在大量数据的时采取的措施。

在这里插入图片描述

接收到的数据,先放到接收缓冲区,接下来应用程序通过socket里的InputStream来读了,代码中读出来的数据就从接收缓冲区删除了。

流量控制

首先并不是窗口越大越好,发的快会瞬间吧接收缓冲区打满,接下来发送的数据,就会丢包,这种情况得不偿失,还不如慢点。
通过流量控制,本质就是限制发送方的速度,ack报文里携带窗口大小这样的字段,这里写的值是建议发送方发送的窗口大小,直接拿接收缓冲区的剩余空间作为窗口大小。当缓冲区满了之后就暂停发送,但是每隔一段时间触发一个窗口探测报文。

拥塞控制

拥塞控制:衡量中间节点的传输能力,通过实验的方式,按照小的速率发送若不丢包则提高速率(扩大窗口大小),如果出现丢包,立即把速率调小,重复上述过程。此过程又称为动态平衡。
在这里插入图片描述

刚开始回给一个小的窗口值,每次翻倍式增长,当到一定阀值就会线性增长,当出现丢包就认为到达上限,此时又将窗口设成一个比较小的值。

实际发送方的窗口大小=min(流量控制窗口,拥塞控制窗口)

延时等待

延时等待:接受方不立即发送ACK,而是等待一会再发送从而提高效率。在这里插入图片描述

假设立即返回的ACK中带有的窗口大小为n,如果稍微等待一下,在返回(这个过程中应用程序也在读取缓冲区中的数据)此时再返回的ACK,窗口大概率比立即返回的窗口大,此时就效率提升了。

捎带应答

捎带应答基于延时等待。
在这里插入图片描述

A发送请求,B立即做出确认应答,当B发送请求通过write写数据,通过一些代码执行到才返回,这俩时机不同,但是要是延时等待,就很有可能将ack和请求合并成一个发送。这也就是为什么四次挥手三次挥完的原因。

面向字节流—粘包问题

当A向给B连续发送多个应用层数据报,这些数据就都紧紧挤在B的缓冲区中,此时B应用程序在读数据的时候,就难以区分一个完整的应用层数据报,很容易读出半个报,多个报的情况。
解决方案

1.定义分隔符,每一个数据报结尾以某个特定字符结尾
2.约定前四个字节,表示整个数据报长度。

关于异常情况

进程关闭/进程崩溃

进程没了,socket是文件,随之被关闭,但是连接还在仍然可以继续四次挥手。

主机关机(正常关闭)

先杀死所有进程,也会触发四次挥手,如果挥完更好,如果没挥完会对端进行重传fin,重传几次都没有ACK,此时尝试重连,如果还不行,直接进行释放连接

主机断电和网络断开

瞬间机器关了,来不及做任何挥手操作。
如果对方是发送方,对端就收不到ACK,此时进行超时重传=》重置连接=》释放连接。
如果对方是接收方,此时对端无法知道是否机器挂了,此时TCP内置心跳包(保活机制),发送方定期发生心跳包。

TCP和UDP的应用场景

绝大部分情况下都可以使用TCP
对于效率要求较高,但是对于不可靠性要求不高的情况下,如同一个机房内网之间的数据传输。

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

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

相关文章

YZ06:加载项是否加载的判断

【分享成果,随喜正能量】人生,因有缘而聚,因情而暖;人生,因不珍惜而散,因恨而亡;活着就要善待自己,不属于自己的不强求,不是真心的不必喜欢,时间在变&#xf…

Spring初识(三)

文章目录 前言一.存储 Bean 对象1.1 类注解的用法1.2 为什么要使用这么多类注解1.2.1 为什么需要五大类注解 1.3 各个类注解的关系1.4 Bean的命名规则1.5 方法注解的使用 二.取出 Bean 对象2.1 属性注入2.2 Setter注入2.3 构造方法注入 三.总结 前言 经过前面的学习,我们已经学…

【C++】STL使用仿函数控制优先级队列priority_queue

文章目录 前言一、priority_queue的底层实现二、使用仿函数控制priority_queue的底层总结 前言 本文章讲解CSTL的容器适配器:priority_queue的实现,并实现仿函数控制priority_queue底层。 一、priority_queue的底层实现 priority_queue叫做优先级队列&…

uview2.0使用u-calendar 的formatter属性,在formatter方法里无法访问this的bug,解决办法!!!!

uview 版本2.0.36 文档 使用该文档的案例,在 formatter打印this也会是undefined。 自己写了个demo 父给子传值v-bind传一个函数,然后在这个函数里面打印this,this是子组件的实例,但是不知道为什么formatter里会打印undefined。希…

pytorch工具——使用pytorch构建一个神经网络

目录 构建模型模型中的可训练参数假设输入尺寸为32*32损失函数反向传播更新网络参数 构建模型 import torch import torch.nn as nn import torch.nn.functional as Fclass Net(nn.Module):def __init__(self):super(Net,self).__init__()#定义第一层卷积层,输入维…

配置NFS服务

环境 环境 ubuntu 10.4 vm 7.1 终端 ifconfig 得到 ubuntu资料 INET ADDR 192.168.0.4 BCAST 192.168.0.255 MASK 255.255.255.0 操作前先关闭防火墙 关闭防火墙: 命令:sudo ufw disable 打开防火墙 命令:sudo ufw enable 配置过程 一 安…

G--爬山---2023河南萌新联赛第(二)场:河南工业大学

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 示例1 输入 3 230 100 200 300 输出 192 示例2 输入 3 900 150 150 125 输出 -1 解析&#xff1a; 二分。 #include<bits/stdc.h> using namespace std; typedef long long ll…

单独在文件中打开allure生成的index.html报告时却显示为loading

【问题描述】&#xff1a;单独在文件中打开allure生成的index.html报告时显示为loading&#xff0c;如下图&#xff1a; 【问题定位】&#xff1a;其实在allure-report下index.html文件是不能直接打开的&#xff0c;出现页面都是loading的情况&#xff0c;这是因为直接allure报…

回归预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 ![6 基本介绍 1.MATLAB实现TCN-BiGRU时间卷积双向门控循…

RT-Thread qemu mps2-an385 bsp 移植制作 :系统启动篇

前言 前面准备了 RT-Thread qemu mps2-an385 bsp 制作相关的环境与相关文件&#xff0c;本篇开始讲解 bsp 如何适配到 RT-Thread CPU 部分已经适配好了&#xff0c;也就是通过 使能 ARCH_ARM_CORTEX_M3 &#xff0c;来使能 rt-thread/libcpu/arm/cortex-m3&#xff0c;这部分不…

使用docker进行MYSQL主从复制(一主两从)

目录 概述主从介绍 主从作用 主从作用有&#xff1a; 主从形式有&#xff1a; 配置步骤 主要配置 1>创建三个进程 2>修改配置文件 3>主机配置 4>从机配置 5>将文件修改后&#xff0c;复制到容器里面 6>进入主机进行配置 6.1>创建用户 6.2>…

从0到1完成UI自动化测试框架搭建之Pytest

上篇文章中&#xff0c;我们学会了如何使用UI Automator2atx编写简单的Android自动化脚本。 但是有个问题&#xff0c;大家可以思考下&#xff0c;光用自动化脚本让它自己动起来&#xff0c;是不是缺了点什么&#xff1f; 我们写测试用例的时候&#xff0c;是不是经常写&…

【C++】string的深入学习与模拟实现

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;初阶数据结构 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对…

Python 模块 ddt 数据驱动测试

简介 ddt 提供了一种方便的方法来实现数据驱动测试&#xff08;Data-Driven Testing&#xff09;。数据驱动测试是一种测试方法&#xff0c;通过将测试数据与测试逻辑分开&#xff0c;可以使用不同的数据集来运行相同的测试用例。这样可以提高测试的灵活性和可维护性&#xff0…

SQL SERVER ANALYSIS SERVICES决策树、聚类、关联规则挖掘分析电商购物网站的用户行为数据...

全文链接&#xff1a;http://tecdat.cn/?p32118 假如你有一个购物类的网站&#xff0c;那么你如何给你的客户来推荐产品呢&#xff1f;&#xff08;点击文末“阅读原文”获取完整文档、数据&#xff09; 相关视频 这个功能在很多电商类网站都有&#xff0c;那么&#xff0c;通…

Flink CEP (一)原理及概念

目录 1.Flink CEP 原理 2.Flink API开发 2.1 模式 pattern 2.2 模式 pattern属性 2.3 模式间的关系 1.Flink CEP 原理 Flink CEP内部是用NFA&#xff08;非确定有限自动机&#xff09;来实现的&#xff0c;由点和边组成的一个状态图&#xff0c;以一个初始状态作为起点&am…

Unity进阶-消息框架的理论知识与实际操作学习笔记

文章目录 Unity进阶-消息框架的理论知识与实际操作学习笔记 Unity进阶-消息框架的理论知识与实际操作学习笔记 笔记来源课程&#xff1a;https://study.163.com/course/courseMain.htm?courseId1212756805&_trace_c_p_k2_8c8d7393c43b400d89ae94ab037586fc 这种框架其实…

实现锂电池形状的数据可视化css+js

1.效果图 2.需求根据后端返回数据改变里面的高度 HTML&#xff1a; <div class"dianchichi"><div class"limian" id"divElementId"></div></div> css: .dianchichi {width: 84px;height: 146px;display: flex;justify-…

Two Days wpf 分享 分页组件

迟来的wpf分享。 目录 一、序言 二、前期准备 三、前端界面 四、后台代码部分 1、先定义些变量后面使用 2、先是按钮事件代码。 首页按钮 上一页按钮 下一页按钮 末尾按钮 画每页显示等数据 每页显示多少条 判断是否为数字的事件 分页数字的点击触发事件 跳转到…

Docker安装Nexus并配置Maven私服

1 准备工作 1 服务器已安装docker, docker各命令无报错 2 通过dockerhub查看nexus的版本信息&#xff0c;此次使用的镜像为&#xff1a;sonatype/nexus3&#xff0c;可以看到latest版本更前的的是3.58.0&#xff0c;我们这次就使用这个版本的nexus3. 2 开始安装 # 下载镜像 do…