UDP/TCP

udp/tcp特征

udp:

  • 无连接
  • 不可靠传输
  • 面向数据包
  • 全双工

tcp:

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

解释:

有连接/无连接:发送消息时,对方是否必须要在线

比如我们聊天程序,我们给对方发送消息,是不管现在是否在线的,这就是无连接

但我们打电话时,必须要对方接通后才能对话,这句话有连接


可靠/不可靠传输:发送消息后,我并不知道对方是否已经接收到了消息

如果我明确知道对方接收到了发送的消息(打电话/已读功能)则是可靠传输,反之则不可靠


面向数据报/字节流:

字节流:数据传输就和流水一样,接踵而至,并不知道完整数据报的头和尾分别在哪

数据报:数据传输是以数据报单位传输的,具有一定的格式


全双工:即可以发送数据,也可以接收数据,一条网络通路是互通的


udp报头结构

udp报头共八字节,四个部分,每个部分2个字节

  • 源端口:发生信息的端口号
  • 目的端口:接收信息的端口号
  • udp报文长度:udp载荷----应用数据包的大小
  • 校验和:判断接收到的数据是否和发送的数据是否一样,如有错,直接丢弃

udp报文长度为两个字节(2^16  65535b),如果应用层数据包的大小超过了64kb怎么办?

  • 此时我们就需要在应用层的代码逻辑中,手动多次地将一个udp数据报分成多次来发送
  • 换用TCP协议,TCP协议并没有应用层数据报的大小限制

tcp报头结构

1.源/目的端口:从哪来,到哪去

2.4位tcp报文长度:这里的单位是字节,故能表示的长度大小位(0----60字节)

3.6位标志位:

  • URG:紧急指针是否有效
  • ACK:确认序号是否有效
  • PSH:提示接收端应用程序立刻从tcp缓冲区把数据读走
  • RST:对方要求重新建立连接,我们把携带此标志位的称为复位报文段
  • SYN:请求建立连接,我们把携带此标志的称为同步报文段
  • FIN:通知对方,本端要断开连接了,我们把携带此标志的称为结束报文段

4.校验和:确认发送与接收数据是否一致 (CRC)

5.十六位紧急指针:表明哪写数据是紧急数据

6.选项前的长度是固定的-----20字节选项长度 = 报文长度 - 20字节


TCP原理:
应答机制

引出:在网络传递信息时,可能会出现后发先置的情况

信息正常顺序送达:

小明---->小红:今天要不要出去玩  小红---->小明:没问题

小明---->小红:借我点钱     小红---->小明:哥稳衮


但网络传输存在后发先置的情况,其接收顺序可能会发送变化,从而变成

虽然消息2是后发的,但是它先于消息1到达,故小红回答哥稳衮,但在小明看来他是先发的消息1,故小明以为小红的回答是:

小明:今天要不要出去玩   小红:哥稳衮

小明:借我点钱   小红:没问题

此时,问题是不是变得和正常的情况完全相反了,不符合我们预期


解决:应答机制

将每条消息进行编号,响应对应序号的消息,此时,即使消息达到的顺序乱了,我们也可以对每个消息进行精准地回复

这个时候就需要用到我们tcp报文结构中的序号了,如何一条报文都是有序号的(包括应答报文),而确认序号只有应答报文才有,当ACK=1时,表示当前报文是应答报文,如果为0则表示是一个普通报文


超时重传

引出:当我们传输数据时不顺利时-------丢包(小概率事件)

  • 数据报丢失
  • 返回的ACK确认序号丢失

此时发送方是无法区分到底是哪种原因导致传输失败的,他只觉得没有接收到ack确认序号

此时TCP就会引入重传机制,并引入一个时间阈值,当发送方发送数据后等待实际超过时间阈值后还是没有收到ACK,此时就会重传一份和之前一摸一样的数据,而这个时间阈值是可配置的,没有固定


那如果重传一次数据后,又丢包了怎么办?

继续重传,当重传到一定次数后,会认为是网络故障,断开重连后再重传,如果此时还是失败,便断开连接。而具体是重传几次后重连,也是可配置的,不确定


同时,你重传的次数不同,时间阈值也随之不同

重传轮数越大,阈值越长,重传的频率越低

因为你重传的次数越多,代表你获得ACK的成功率越低,即使你重传地快,一样还是得不到ACK,白白浪费资源


故TCP的可靠运输,就是一句应答机制和超时重传机制所实现的


连接管理:
三次握手:

1.连接流程:

A发生SYN向B请求建立连接,B接收到请求后返回给A一个ACK,同时发生一个SYN请求和A建立连接,A接收到B的请求后返回给B一个ACK

2.这里实际上是4个步骤,为什么只有三步呢?

其实就是把B向A返回的ACK和SYN合并到一起了

3.那么为什么要合并呢?

封装分用一次的成本无疑比封装分用两次的成本低


三次挥手的意义

1.确认彼此都是对方交流的对象

2.确认彼此的接收发送功能都是正常的

3.在三次握手的过程中,可以来商讨一些彼此之间的秘密


四次挥手:

挥手流程:

1.A向B发送FIN报文,此时A进入FIN_WAIT_1状态

2.B接收到FIN报文后,返回ACK,进入到CLOSE_WAIT状态

3.A接收到B的ACK应答报文后,进入FIN_WAIT_2状态

4.B处理完数据后,向A发送FIN报文,进入LAST_ACK状态

5.A接收到B发送的FIN报文后,发送ACK报文,进入TIME_WAIT状态

6.B收到ACK报文后,断开连接,此时处于CLOSE状态

7.A经过2MSL时间后,进入CLOSE状态


问题:

1.为什么挥手中间的两次操作不能像握手一样合并成一个

首先我们得知道一个点:

FIN的发送是由我们程序员自己控制的,当我们调用操作系统给的socketAPI中的close方法时,就会发送FIN报文。而ACK是内核自动发送的,当接收到FIN,内核会立即自动返回一个ACK。所以在发送ACK和FIN报文之间,存在着一个很明显的时间差。因为你程序员在调用close方法之前做了什么操作,需要多少时间都是不确定的,故这两步操作无法合并成一步,不处于同一时机


2.为什么当A收到B的FIN后是进入TIME_WAIT状态,而不是CLOSE状态?

1).由上方所述,当接收到FIN报文后内核会自动返回一个ACK,如果A直接断开连接,处于CLOSE状态。那么如果此时ACK没有顺利到B呢?此时不就造成丢包问题了

2.)充分接收B在网络中还在传输的数据--------由于FIN之前的代码业务代码都是不同的,如果在调用close方法前执行了很多业务,传送了大量数据,此时A接收到FIN后如果直接变为CLOSE状态,那么就有可能没有完整地接收B传输给A的消息


3.2MSL是什么?怎么来的?

MSL:Maximum Segment Lifetime(最大报文存活时间),根据字面意思我们就能理解了,当超过此时间后报文被消灭,连接被断开

那么为什么是2MSL--------一来一回嘛

MSL具体是多少:通常情况下,这个值是60s,但是还是具体情况具体分析,并不是一个固定值,更准确地说MSL更像一个经验值,保证了99%的数据的传输时间都不会超过MSL


三次握手和四次挥手就决定了TCP可连接的熟悉
滑动窗口(效率机制):

如果我们每发一次消息,就需要等待接收方返回ACK后,再发一条消息,此时效率是否有点慢了呢?(可以 但不快)


解决:我们一次多发几条消息,其本质是将等待时间重叠了

  1. 窗口大小:指的是无需等待返回的ACK即可发送数据的最大值如上图,此时的窗口大小就是4000,故前四个发送的请求,直接发送,无需等待ACK
  2. 收到第一个ACK后,滑动窗口就开始往后移动了。(注意:并不是需要等待全部的ACK返回才能继续发送后面的请求,而是只要ACK小于窗口大小对应的消息数时,就往后移动,使需要等待的ACK始终是4条(就上图))
  3. 操作系统为了维护这一个滑动窗口,会在发送方开辟一个发送缓冲区来记录还没有应答的数据,只有接收到ACK的数据才会被冲刷掉

问题:

1.ACK丢了

没啥事,因为确认序号的定义是:此序号前的序号全都已经确认了

比如你发送的1-1000序号包丢了,但你ACK返回了2001,此时表示1-2000的序号都已经被确认了,所以中间的确认序号丢掉几个无关大雅,只要有后续的ACK到达即可

2.数据丢了

如果此时我们的1-1000序号包丢了,1001-2000的序号包成功发送到B,此时B回给A的ACK是1,此时返回的ACK和你发送的数据包已经没啥关系了,此后B就会一值索要序号1开头的数据包,如果B发现接下来几个仍然不是1开头的数据,那么这时候就需要对1-1000序号包进行重传了-------快速重传


快速重传:在发生数据丢包时尽快重传丢失的数据包,减少网络延迟

过程:

1.当接收方收到三个连续的重传请求后,仍没有收到对应缺少的数据包

2.接收方发送快速重传请求

3.发送方接收到快速重传的请求,进入快速重传的状态模式

4.发送方立即重传最后一次发送的数据包

5.发送方停止新的数据包的发送,等待接收方的确认


流量控制----控制发送方的窗口大小

前面说到,窗口大小决定着无序等待接收方返回ACK即可发送消息的多少,故窗口大小越大,吞吐量也越大但是窗口大小能无限大下去嘛?

这显然不符实际,窗口大小太大,会大量的消耗资源,且接收端的处理能力也跟不上,发的再快也是白发,故流量控制的工作就是,根据接收方的消息处理能力,来协调发送方的发送速率


当窗口大小为0时,发送方就得停止发送数据,在暂停发送的过程中,会给B定期发送窗口探测报文,来触发查询此时的窗口大小

比如喝瓶子中的水,当水被喝完后,我会时不时地给小卖部老板打电话,问有没有进水来


在前面的TCP首部结构中,提到了一个16位的窗口大小,这表示窗口的大小最大为64kb嘛?

实际上,在选项中存在着一个窗口拓展因子M,真正的窗口大小即为窗口大小左移M位

也就是如果如果此时M为,那么实际的窗口大小为64 << 2  = 256kb


拥塞控制:考虑传输过程中中间节点的处理能力

tcp引入慢启动机制,先发少量的数据,来勘测一下目前网络传输的环境(是否拥挤)

此时引入一个概念:拥塞窗口

1.起始值为1,当收到一个ACK确认序号后,拥塞窗口+1

2.每次发送数据包的时候,将拥塞窗口大小和接收端返回给发送方的窗口大小做比较,取较小值作为实际发送的窗口


虽然叫法叫做慢启动,但其增长速度是极快的------指数级增长,为了防止其增长得过快,为其设置了一个阈值,当拥塞窗口超过此阈值的时候,不再是指数级增长,而是成线性增长

1.每当慢启动开始的时候,慢启动阈值为窗口最大值(16位)

2.当遇到少量丢包(超时重传)后,慢启动阈值会变成原来的一半,拥塞窗口也重新变成1

3.故tcp网络吞吐量是一个循环的过程,一开始逐渐增高,当遇到网络堵塞后吞吐量又变成很低,然后又依照之前的增长顺序循环

故拥塞控制的意义为:尽可能快地将数据传输给接收方,又避免给网络太大的传输压力


延迟应答:
  • 如果我们接收方收到消息后就立即返回ACK,假设此时的传输数据只有400k,而接收方的缓冲区有1M,此时的窗口大小400k远没有达到缓冲区的范围大小,使效率降低
  • 如果我们延迟一点时间再应答,这时候可能就又有新的数据传过来了,此时大小为1M,这时候接收方缓冲区就被充分利用了,返回的窗口大小也是1M,效率提高

窗口越大,网络吞吐量越大,网络传输效率越高


Nagle算法:解决tcp传输小包,降低传输效率的问题

试想:如果你的应用层数据包只有1字节,但由于tcp报头结构,其选项前首部固定的20字节,那么此时你发送的数据就是21字节,这些小包的发送会使网络出现拥塞

故该算法要求:一个TCP连接中,至多只能有一个未被确认的小分组,在该分组未被确认前不能发送其他的小分组,该算法会收集其他小分组,在某一合适时机发送出去


Nagle算法原理:MMS(最大报文长度)

  • 如果有数据要发送,且窗口大小大于MSS,或者包含FIN报文,则立即发送
  • 如果有未确认的数据,且新数据可以与未确认的数据进行合并(新数据长度+未确认数据长度 < MMS),则新数据内容可以拼接在未确认数据后面
  • 如果新数据不能与未确认数据合并,且未确认数据此时已收到ACK,那么会分别发送新数据及未确认数据
  • 如果新数据不能与未确认数据合并,且未确认数据此时还是没有收到ACK,这是会等待直到收到未确认数据的ACK后,新数据才能被发送

那么何时进行延迟应答呢? 每几个包之间进行延迟呢?

  • 每隔N个包之间:通常取2
  • 超过最大时间限制:通常取200ms

捎带应答:

还记得我们三次握手的合并吗,而这里是有概率的合并

由于我们的延迟应答机制,可能会使我们的ACK(内核调用,立即返还)和我们的业务操作变成同一时机,有概率的合并在一起返回给发送端

故延迟应答机制增加了合并的几率


面向字节流:

缓冲区:

创建tcp连接时,内核会分别创建一个发送方/接收方缓冲区

发送方:

  • 当发送数据时(write),会先进入发送方缓冲区
  • 当发送数据的长度超过缓冲区,会被拆分成多个tcp数据包发出
  • 当发送的数据少于缓冲区时,就会先在里面等待,等待后续的数据继续写入,当缓冲区长度快要满时,再一起发送出去

接收方:

  • 数据从网卡驱动到接收方缓冲区
  • 接收方通过read将数据读出来

由于缓冲区的存在,读数据和写数据不需要一一匹配

1.比如,有一个100k的数据,我可以一次100k的数据包,这样一次就能发送出去。也可以一次发10k,发10次发送出去

2.当我接收这个100k的数据时,我可以一次读100k数据,一次读完。也可以一次读10k数据,读10次读完


我们知道,tcp传输是面向字节流的,而这就会引入一个问题-------粘包问题

试想:所发送来的数据都是和水一样源源不断连续的,那么我们该如何区分每一部分数据的头和尾呢?或者说,如何看懂一篇没有任何标点符合的文章呢?


解决:约定好应用层协议,明确数据与数据之间的分界线

1.定长:确定每次传输的数据长度都是固定的,按照固定的长度解析即可

2.不定长:确定与数据内容无冲突的分隔符,每当遇到分隔符时即分割字符流数据


那么udp数据报是否会存在粘包问题呢? ------- 不存在

  1. udp是基于数据报发送的,具有消息保护边界
  2. 不能合并或拆解,发送接收的数据都是一个一个的,每一个数据报都是完整的

但udp数据报虽然不存在粘包问题,但由于其是无连接的,会存在数据丢失/重复/乱序等问题


TCP异常情况:

1.进程结束:发送FIN终止报文

2.机器重启:发送FIN终止报文

3.网络断开:此时接收端还认为连接存在,但如果接收方执行到写操作,就会立马意识到连接已经不在了,这时候接收端就会向发送端发送RST报文(请求建立连接)

即使接收端没有执行写操作,TCP内部也内置了一个保活定时器,会定期询问对方是否还在线,连接是否还处于正常状态


小结:以上就是TCP传输的主要机制,其主要作用于两个功能:传输可靠:提高性能

传输可靠:

  • 校验和
  • 序列号/确认序列
  • 应答机制
  • 超时重发
  • 传输管理(三次握手 四次挥手)

提高性能:

  • 滑动窗口
  • 流量控制
  • 拥塞控制
  • 延迟应答+Nagle算法
  • 捎带应答

欢迎大家继续完善相关内容及补充~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++笔试练习笔记 【2】: 数字统计 BC153 两个数组的交集 NC313 点击消除 AB5

文章目录 数字统计分析题目代码部分 两个数组的交集题目分析代码部分 点击消除题目解析代码部分 数字统计 分析题目 这个题涉及到两个知识点&#xff0c;就是枚举和数字的拆分 那么我的思路是进行遍历&#xff0c;拆分数字判断二的个数&#xff0c;枚举进行计数 那么数字的拆分…

C++协程库封装

操作系统&#xff1a;ubuntu20.04LTS 头文件&#xff1a;<ucontext.h> 什么是协程 协程可以看作轻量级线程&#xff0c;相比于线程&#xff0c;协程的调度完全由用户控制。可以理解为程序员可以暂停执行或恢复执行的函数。将每个线程看作是一个子程序&#xff0c;或者…

java同步大量数据到本地数据库方法总结

最近在做一个需求&#xff0c;就是我需要对三方接口调用的数据存放到本地的数据库里的数据表里面。那么一开始我就是直接一条一条save&#xff0c;结果发现耗时非常严重&#xff0c;后面我就进行了改进。就是分批次去同步或者分批次去异步。 现在我直接贴出我写的代码&#xf…

《MySQL对数据库中表的结构的操作》

文章目录 一、建表二、查看表结构所有能查看到数据库&#xff0c;表的操作痕迹的本质都是服务器保存下来了这些操作记录。 三、修改表1.改表名字2.添加表记录3.添加表的更多字段4.修改表的字段5. 删除表的字段 总结 以下的数据库表的操作全是基于user_db这个数据库操作的&#…

maven聚合,继承等方式

需要install安装到本地仓库&#xff0c;或者私服&#xff0c;方可使用自己封装项目 编译&#xff0c;测试&#xff0c;打包&#xff0c;安装&#xff0c;发布 parent: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://mav…

Golang图片验证码的使用

一、背景 最近在使用到Golang进行原生开发&#xff0c;注册和登录页面都涉及到图片验证码的功能。找了下第三方库的一些实现&#xff0c;发现了这个库用得还是蛮多的。并且支持很多类型的验证方式&#xff0c;例如支持数字类型、字母类型、音频验证码、中文验证码等等。 项目地…

《MySQL是怎样运行的》读书笔记(二) 从一条记录说起-InnoDB记录结构

前言 到现在为止&#xff0c; MySQL 还是一个黑盒&#xff0c;只知道使用客户端发送请求并等待服务器返回结果 那么表中的数据到底存到了哪里?以什么格式存放的? MySQL 是以什么方式来访问的这些数据? 相应的知识储备我只知道MySQL 服务器上负责对表中数据的读取和写入工…

C语言:文件操作(下)

片头 嗨&#xff01;小伙伴们&#xff0c;在前2篇中&#xff0c;我们分别讲述了C语言&#xff1a;文件操作&#xff08;上&#xff09;和 C语言&#xff1a;文件操作&#xff08;中&#xff09;&#xff0c;今天我们将会学习文件操作&#xff08;下&#xff09;&#xff0c;准…

C语言异步编程

回调函数在异步编程中有着重要的作用&#xff0c;在接口编程应用广泛&#xff0c;实战中经常会注册一个回调函数来接收其他程序返回的数据&#xff0c;这样做的好处是调用者无需主动去获取被调用者的数据&#xff0c;仅仅需要回调&#xff0c;让被调用者去传送数据&#xff0c;…

VS code 同步odata服务

在做UI5得开发过程中&#xff0c;经常会出现odata需要更新 那么已经加载过得项目如何去跟新odata服务呢 可以通过如下步骤 1.右键打开应用信息 2.找到manage service models 3.点击编辑 4.选中 刷新并保存

C++ | Leetcode C++题解之第60题排列序列

题目&#xff1a; 题解&#xff1a; class Solution { public:string getPermutation(int n, int k) {vector<int> factorial(n);factorial[0] 1;for (int i 1; i < n; i) {factorial[i] factorial[i - 1] * i;}--k;string ans;vector<int> valid(n 1, 1);…

mysql主库delete一个没主键的表导致从库延迟很久问题处理

一 问题描述 发现线上环境一个从库出现延迟&#xff0c;延迟了2天了&#xff0c;还没追上主库。 查看当前运行的sql及事务&#xff0c;发现这个sql语句是在delete一个没主键的表。 二 问题模拟 这里在测试环境复现下这个问题。 2.1 在主库造数据 use baidd; CREATE TABL…

arthas watch怎么监控指定参数值?

watch com.codex.terry.controller.HelloWorldController getUserInJson2 "{params,returnObj}" params[0] "world" -v 要分析的代码&#xff1a; 浏览器请求http://localhost:8080/say/tt&#xff0c;arthas控制台打印的信息如下&#xff1a; 浏览器请…

LeetCode45:跳跃游戏Ⅱ

题目描述 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n …

C++成员初始化列表

我们在类的构造函数中使用成员初始化列表可以带来效率上的提升&#xff0c;那么成员初始化列表在编译后会发生什么就是这篇文章要探究的问题 文章目录 引入成员初始化列表用成员初始化列表优化上面的代码成员初始化列表展开成员初始化列表的潜在危险 参考资料 引入 考虑下面这…

TDengine写入2000万数据查询体验

最近在寻找时序数据库&#xff0c;想应用在公司的项目上。 上一篇文章实验了InfluxDB:windows上使用influx2.7学习,还学习了flux语言&#xff0c;最后发现宽表查询比较困难&#xff0c;就放弃了&#xff0c;于是决定试试国产时序数据库TDengine 参考 官方文档&#xff1a;htt…

有货源和分销单品爆款玩法课

该课程专注于教授如何利用有货源和分销渠道&#xff0c;打造单品爆款销售策略。学员将学习货源获取、产品定位、市场推广等关键技巧&#xff0c;通过实战案例和实操训练&#xff0c;掌握成功销售单品爆款的方法&#xff0c;提升销售业绩和市场竞争力。 课程大小&#xff1a;6.…

RabbitMq基础概念知识复习

消息拥有消息头和消息体&#xff0c;消息具有rounting key&#xff0c;主题交换机和扇形交换机都是发布与订阅的实现方式&#xff0c;主题交换机用于匹配接收的消息的rount key 动态匹配模式匹配到多个符合的队列&#xff0c;扇形fanout交换机则不会使用消息的路由key&#xff…

【AIGC调研系列】InternVL开源多模态模型与GPT-4V的性能对比

InternVL和GPT-4V都是多模态模型&#xff0c;但它们在性能、参数量以及应用领域上有所不同。 InternVL是一个开源的多模态模型&#xff0c;其参数量为60亿&#xff0c;覆盖了图像/视频分类、检索等关键任务&#xff0c;并在32个视觉-语言基准测试中展现了卓越性能[2]。InternV…

CYP76AKs的功能分化塑造了鼠尾草属中松香烷型二萜化合物的化学多样性-比较转录组-文献精读12

Functional divergence of CYP76AKs shapes the chemodiversity of abietane-type diterpenoids in genus Salvia "CYP76AKs的功能分化塑造了鼠尾草属中松香烷型二萜化合物的化学多样性"&#xff0c;一片比较转录组的文献&#xff0c;类似比较转录组分析揭示了116种…