UDP/TCP

news2024/11/16 15:56:13
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算法
  • 捎带应答

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

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

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

相关文章

HTML5实用大全(Part.1)

引言&#xff1a; 哈喽&#xff0c;各位小伙伴们&#xff0c;在本篇博客我将带领大家走进前端中的HTML5,利用HTML我们将可以在网页上自我创作内容&#xff0c;现在学起来&#xff0c;不久后自己也能制作一个花哨的项目了呢&#xff0c;那么&#xff0c;我们开始吧&#xff01; …

使用c++类模板和迭代器进行List模拟实现

List 一、创建节点结构二、创建迭代器类1、类的结构2、一系列的运算符重载 三、创建list1、细节把握2、迭代器函数3、构造函数和析构函数4、增删查改的成员函数 一、创建节点结构 template <class T>//节点结构 struct ListNode {ListNode<T>* _next;ListNode<…

交通 | 电动汽车车辆路径问题及FRVCP包的调用以及代码案例

编者按&#xff1a; 电动汽车的应用给车辆路线问题带来了更多的挑战&#xff0c;如何为给定路线行驶的电动汽车设计充电决策是一个需要解决的难题&#xff0c;本文介绍了开源python包frvcpy使用精确式算法对该问题求解。 文献解读&#xff1a;Aurelien Froger, Jorge E Mendo…

python 怎么调用R

如何在python中调用R&#xff1f;这其中包括了如何调用R的对象&#xff08;函数和包&#xff09;&#xff0c;R和python的对象如何互相转换&#xff0c;以及如何调用R的脚本&#xff08;外界参数的输入&#xff09;。python提供了一个模块rpy2&#xff0c;可以较好地完成这项工…

【深耕 Python】Data Science with Python 数据科学(18)Scikit-learn机器学习(三)

写在前面 关于数据科学环境的建立&#xff0c;可以参考我的博客&#xff1a; 【深耕 Python】Data Science with Python 数据科学&#xff08;1&#xff09;环境搭建 往期数据科学博文一览&#xff1a; 【深耕 Python】Data Science with Python 数据科学&#xff08;2&…

什么是发售?

什么是发售? 很多人不知道什么是发售,因为这个词刚被广而告之,在这里普及一下什么是发售? 发售,它是通过一套流程,把你的产品疯狂大卖的一种技术。通常有三个步骤,就是造势、预售、发售。那么这三个词怎么理解呢? 第一步:造势 造势的核心是引发关注,但是不做销售…

【开源设计】京东慢SQL组件:sql-analysis

京东慢SQL组件&#xff1a;sql-analysis 一、背景二、源码简析三、总结 地址&#xff1a;https://github.com/jd-opensource/sql-analysis 一、背景 开发中&#xff0c;无疑会遇到慢SQL问题&#xff0c;而常见的处理思路都是等上线&#xff0c;然后由监控报警之后再去定位对应…

06 - 步骤 add constants

简介 Add Constants 步骤是用于在数据流中添加常量字段的步骤。它允许用户在数据流中插入一个或多个常量字段&#xff0c;并为这些字段指定固定的数值、字符串或其他类型的常量值。 使用 场景 我需要在数据清后&#xff0c;这个JSON 字符串有一个固定的行流数据。 1、拖拽…

如何判断自己是不是偏执型人格障碍

什么是偏执性人格障碍&#xff1f; 偏执型人格障碍是比较常见的一种人格障碍类型&#xff0c;其特征是偏执&#xff0c;和一般的固执&#xff0c;顽固有所不同。通常我们说一个人很固执或顽固&#xff0c;更多是因为其坚持己见&#xff0c;不受他人的思想左右&#xff0c;其本…

代谢组数据分析七:从质谱样本制备到MaxQuant搜库

前言 LC-MS/MS Liquid Chromatography-Mass Spectrometry&#xff08;LC-MS/MS &#xff0c;液相色谱-质谱串联&#xff09;可用于残留化合物检测、有机小分子检测、鉴定和定量污染物以及在医药和食品领域添加剂检测和生物小分子等检测。 LC-MS/MS一般包含五个步骤&#xff…

yolov5口罩检测实战

学习资料提要&#xff1a;手把手教你使用YOLOV5训练自己的目标检测模型-口罩检测-视频教程_搭建yolo目标检测的环境. 使用yolo-air模块来做实验-CSDN博客 在B站上有这个UP主的实操视频 一 环境安装 1.先在anaconda prompt 里面 (1)conda activate 会转为&#xff08;base&…

【LeetCode刷题】875. 爱吃香蕉的珂珂

1. 题目链接 875. 爱吃香蕉的珂珂 2. 题目描述 3. 解题方法 简单的用我自己的理解来解释一下这道题的意思。 所以也就是说找到一个速度k&#xff0c;看还有没有比k更小的速度能吃完数组中的香蕉&#xff0c;如果有则继续寻找&#xff0c;没有则是k这个速度。就好比上面的解释…

HarmonyOS 4.0(鸿蒙开发)01 - 怎么学习鸿蒙引导篇

作为公司的全栈开发工程师 以及 未来的发展是有鸿蒙这个阶段的&#xff0c;以及本身具有这个技术栈由此后续会分享自己在实战中学习到的东西&#xff0c;碰到的bug都会分享出来&#xff0c;这是引导篇期待后续的更新 学习目标&#xff1a; 理解HarmonyOS操作系统的架构和开发…

Django后台项目开发实战八

添加候选人提交简历功能 第八阶段 安装第三方注册包 pip install django-registration-redux 在 setting.py 注册&#xff0c;并添加配置 INSTALLED_APPS [grappelli,registration,django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.…

展会资讯 | 现场精彩回顾 阿尔泰科技参展2024第23届中国国际(西部)光电产业!

2024第23届中国国际&#xff08;西部&#xff09;光电产业博览会&#xff0c;在成都世纪城新国际会展中心圆满落幕&#xff01;来自各地的光电领域设备及材料厂商汇聚一堂&#xff0c;展示前沿技术及创新成果。 展会现场&#xff0c;来自全国各地的500余家企业就精密光学、信息…

ubuntu22.04 cmake 配置mysql

报错信息&#xff1a; CMake Error at CMakeLists.txt:33 (find_package): By not providing “FindMySQL.cmake” in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by “MySQL”, but CMake did not find one. Could not…

MySQL:设置唯一索引还是出现重复数据

一、MySQL中null和null不相等 MySQL中&#xff1a;两个值比较会出现&#xff1a;true、false、null 三种情况&#xff1b; null和null相比较会出现未知的类型 二、然后看完这个视频 美团二面&#xff1a;我记得明明加了mysql唯一索引&#xff0c;为啥还会出现重复数据吗&…

手拉手springboot整合kafka

前期准备安装kafka 启动Kafka本地环境需Java 8以上 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。 Kafka启动方式有Zookeeper和Kraft&#xff0c;两种方式只能选择其中一种启动&#xff0c;不能同时使用。 Kafka下载…

【独立版】商城盲盒源码带uniapp(H5+小程序+APP三端)全开源

前端uniapp开源代码&#xff0c;可用HBuilder工具无限发行H5、小程序和打包app&#xff0c;后端PHP开源源码&#xff0c;支持二开。 内有安装搭建教程&#xff0c;轻松部署&#xff0c;搭建即可运营&#xff0c;内置永久免费更新地址&#xff0c;后续无忧升级。 【独立版】商…

github托管静态页面

免费在线上空间&#xff0c;不用简直就是浪费&#xff0c;关键还不限流量赶紧去折腾一下 这是搭建的GitHub托管网页&#xff0c;由于是GitHub的服务器&#xff0c;国内访问会非常&#xff01;慢 下载 Watt Toolkit 这里我建议下载一个软件 Watt Toolkit 它是一个开源跨…