网络原理-UDP和TCP

news2024/12/27 15:03:52

在传输层中有两个非常重要的协议,UDP和TCP,现在就来研究一下这两个协议。

UDP

报文格式

我们观察可以发现,里面UDP报文长度为2个字节,那么是多少呢?我们需要快速反应如下固定字节数据类型的取值范围:

字节大小有无符号取值范围
1个字节有符号-128-127
1个字节无符号0-255
2个字节有符号-32768-32767
2个字节无符号0-65535
4个字节有符号-21亿-21亿
4个字节无符号0-42亿

源端口:2个字节,无符号,取值0-65535.

目的端口:2个字节,无符号,取值0-65535.

UDP报文长度:2个字节,无符号,取值范围0-64k,也就是说一个UDP最多能传输64kb的数据,这在当今是一个很小的数字(现在一个文件动不动就几个G).

说明:

能否将这个长度变大呢?理论上可以,但是几乎无法做到。

理论上,我们只需要修改系统内核中udp的参数,将unsigned short改成int就可以增加长度,但是我们不能只修改自己电脑的,我们还得修改别人的,怎么说每个人都改呢???

不过我们还可以将数据拆分成多组进行传输或者使用tcp代替udp,tcp没有报文长度限制。

校验和:使用了一种简单粗暴的校验算法,把UDP数据报中的每个字节都依次进行累加。

说明:

为什么要使用校验和呢?因为网络传输本质上是光信号/电信号传输,会受到磁场,高能粒子的干扰,就有可能使传输的数据突变,即0变1,我们需要使用校验和来确保传输的数据没有变化。

一般UDP中校验和是将数据报中每个字节都累加,可能会溢出,但是不要紧,当接收方收到数据了后,再按照同样的方式进行累加,如果得到值一样,就是正确的。万一前面的字节值变小了,后面的变大了,一加一减没变,又该如何应对?这种情况是可能出现,但是概率极低,毕竟工程上有一些误差也能接受。

TCP

报文格式

 

 

序列号:给传输的数据进行编号。发送方每发送一次数据,序列号的值就累加一次该数据字节数的大小,可以用来解决乱序的问题。

乱序问题:

为了追求效率,数据会被进行分组,例如有一个2000字节的数据包,被分为两组1-1000、1001-2000,从A端发送到B端,但网络的路径非常多,这两组数据可能会走不同的路线,又因为每个路由器/交换机的繁忙程度不一样,转发的过程也就不一样,因此就不能保证先发先至了,此时我们需要搞清楚哪个数据在前,哪个数据在后,就可以根据序列号来确定。

确认应答号:用在接收方,表示期望下一次接受的数据的序列号,发送方收到这个确认应答号可以认为在这个序号前的数据都被接收了,用来解决丢包问题。

丢包问题:

由于网络的结构复杂,某一时刻某一路由器/交换机数据量非常多,就导致了设备非常繁忙,数据处理的排队时延会很大,此时就有可能采取丢弃策略,就产生了丢包现象,那为了知道丢了哪些包,需要通过确认应答号告诉对方,哪部分的数据没有收到。

首部长度:表示的是TCP报头的长度。TCP报头的前20个字节是固定的,选项部分可以有也可以没有,因此TCP报头的长度是可变的,取值范围为:0*4byte ~ 15 * 4 byte。

保留位:暂时不用,为以后升级留下空间。

标志位:

  • ACK:该位为1时,表示确认应答的为有效字段。

  • RST:该位为1时,表示TCP连接中出现异常必须强制断开连接。

  • SYN:该位为1时,表示希望建立连接,并在设置序列号字段的初始值。

  • FIN:该位为1时,表示不会有数据发送,希望断开连接。

特性

由于TCP中很多特性,在这列举比较熟知的。

一、确认应答

确认应答是保证”可靠性“最核心的机制

确认应答就是告诉对方我收到消息了。发送方发出一个数据包,如果接收方收到了,就返回一个数据包告诉发送方我收到了。

确认应答机制往往配合着确认序号与ACK标志位使用。当ACK标志位为1时,确认序号为有效值,此时这条报文就是一个应答报文,告诉发送方我这边收到了,发送方可以根据确认序号看看有没有丢包的情况。

二、超时重传

由于网络的情况非常复杂,避免不了出现一些丢包的现象,那又该如何处理呢?此时可以大致分为两类情况,一种是发送端发送的数据包丢了,另一种是接收端的应答数据包丢了。

情况一:

如果是发送端发送的数据包丢了,此时发送端就一直接收不到ACK数据包,我们可以通过设置一个超时时间,即过了这个时间还没有收到ACK的话,就再发一次数据包。

总的来说就是没收到应答,就再发一次。

情况二:

如果是接收端已经收到了这个数据,但是应答报文丢了,此时发送端无法区分是否是第一种情况,所以还是会进行重传,接收端就需要进行去重操作。然后再次发送一个应答报文。

如何去重?

使用序列号作为判定的依据。tcp会在内核中给每个socket对象都安排一个内存空间,相当于一个队列,收到的数据就会被放到这里面,并按照序号排列好(还解决了乱序的问题),当来了一个重复的数据以后,就可以根据索引值判断是否出现过了。


丢包本质上是一个概率事件,不可避免,而且随着重传的次数,概率会大幅降低。我们需要合理的设置超时时间。

具体数值可以手动配置,我们更应该去关注里面的策略。

超时时间不是一个固定的值,会随着超时轮次增加。如果好几次都没重传成功的话,说明此时网络本身的丢包率非常高,可能遇到了非常严重的故障,需要拉长一下重传时间,给网络恢复留有一个时间。超时重传的轮次也不是无限的,达到一定次数就会尝试重置tcp连接,设置RST标志位,如果RST报文也丢了,说明此时网络严重故障,那就会放弃连接。

三、连接管理

三次握手

TCP是面向连接的协议,所以使用TCP前必须先建立连接,而连接的建立是通过三次握手来进行的。不过三次握手本质上是"四次握手",只是将其中的两步合并成了一步。

ACK是应答报文,SYN是同步报文,表示申请建立请求。


为什么要进行三次握手?

1、验证通信路径是否通畅,双方的发送和接受能力是否正常

TCP要想保证可靠传输,就得先知道有没有路径以及路径是否通畅(网络拥堵会出现历史连接原因,造成资源的浪费),然后通过三次握手,确定双方是否有发送和接受的能力。只有确定了双方都有接收和发送的能力,才能进行后续的可靠传输。

2、协商必要的参数

通信的时候会涉及到一些参数,比如序列号。由于网络是时刻变化的,会出现先发后至的现象,这时我们可以通过序列号来判断这个消息是不是合法的,即可能这个数据是上一次的连接中的。


那是否可以只进行两次握手呢?四次是否可以?

如果值进行两次握手的话,B端就无法知道A端能否接受数据,以及自己的数据有没有发过去,也就无法保证参数进行了协商,即不能保证双方的序列号是同步,并且如果出现了网络较为拥塞的时候,建立连接的消息重发了好几次,服务器在第一次握手的时候就会建立连接,即创建了一个socket对象,造成了资源的浪费。

如果是进行四次握手的话,本质上就是将三次握手的第二次握手拆开来,而三次握手就可以建立可靠的连接了,多了反而也会浪费资源。

四次挥手

在进行通信后,由于前面的连接会消耗资源,因此我们还需要进行断开连接来释放资源。由于断开连接涉及到了四次通信,因此也被称为是四次挥手。

四次握手能变成三次握手吗?理论上是可以的,当我们调用socket.close方法足够快的时候,即收到关闭请求的后续没啥业务逻辑,就可以合并。但是一般服务器后续还有很多的收尾工作要处理,这时候close方法执行的时机比较慢,就不能合并了。

丢包问题

由于网络通信的复杂,可能会出现丢包,这时候怎么办呢?

一个原则,收不到回应就重传,重传多次还收不到,那就单方面断开连接。

如果第一次挥手丢了,那么就重传,一直收不到回应就断开连接。

如果第二次挥手丢了,由于客户端无法区分,客户端会重传FIN报文,跟第一次挥手丢了同理。

如果第三次挥手丢了,重传,一直收不到回应,就断开连接。

如果第四次挥手丢了,此时站在客户端的角度,客户端收到了服务器的FIN报文并已经发出ACK报文确认了,但是客户端还不能立马释放连接,因为还不能确定服务器是否收到,因此会等待一个2*MSL的时长,在此期间没收到重传的FIN报文,就可以释放连接了。如果丢包了,服务器会重传FIN报文,客户端也就可以回应ACK报文了。

四、滑动窗口

滑动窗口机制是用来提高TCP的传输效率,让TCP在保证可靠的前提下,效率别要太低。虽然滑动窗口能提升TCP的效率,但是这也是有限的,还是不可能比UDP高。

本质就是节省了应答时间。之前是每发一次数据就需要等待一个确认报文的时间,使用滑动窗口后,可以在等待确认报文的时间内,再多发几次数据。


丢包问题

在发数据的时候,丢包情况分为两种:1)数据报了 2)确认应答(ACK)丢了

1)数据丢了

由于前面的确认应答机制,我们TCP协议中的确认序号字段会记录当前发到哪个数据了,如果前面某一个数据丢了,确认序号不会改变,依旧和上一次应答的确认序号是一样的,后面客户端连续收到了服务器索要的相同确认序号的数据时,客户端就明白了丢了哪部分数据,然后就可以进行重传。

2)确认应答丢了

确认应答丢了并不要紧,只要后续确认应答的序号比前面确认应答的序号大的话,就可以理解为,前面的数据都已经接收到了,如果所有ACK都丢了,说明网络出现了重大故障,此时也不满足网络可靠的前提条件了。

五、流量控制

流量控制是作为滑动窗口的补充,理论上滑动窗口越大,传输效率就越高,但是当窗口大小达到一定程度后,接收方可能就处理不过来了,或者说网络传输上的某条链路就处理不过来了,这样就会出现丢包,就得进行重传,结果适得其反了。因此我们需要进行流量控制,让发送方慢一点~

流量控制就是根据接收方的接收能力,来限制发送方的速度,即限制窗口大小。当接收方接收数据的时候,会先将数据存储在缓存区中,因此可以是用缓存区中的剩余空间大小来作为窗口的大小,即修改TCP的中窗口大小字段。

大致流程:

首先客户端先发送一下数据,看看窗口大小多少合适,然后根据窗口大小发送数据,当窗口大小为0的时候就不发数据,期间会发送窗口探测包,来询问服务器啥时候有空?一旦发现不是0了以后,就继续开始发数据。这样接收方可以根据窗口大小来限制发送方的传输速度了。

六、拥塞控制

上述的流量控制是针对接收方的处理能力来判断当前的窗口大小,但是由于在传输的过程中会经过许多节点(路由器/交换机),那么这些中间节点的处理能力是否能达到窗口大小呢?

由于路过哪些节点,在一开始的时候是无法确定的,因此设计TCP的大佬们选择使用"实验"的方式来测试路径节点的接收能力,然后综合分析计算得出一个值,后续再发送数据的速度就不应该超过这个值(木桶效应)。

拥塞控制具体是这样展开的:

1.慢启动:刚开始通信的时候使用一个小窗口,如果传输顺利,没有丢包就会进行扩大窗口。

2.指数增长:在传输顺利后,拥塞窗口大小就会指数增长。

3.线性增长:当指数增长到一个阈值的时候,就会从指数增长转变为线性增长。

4.拥塞窗口回归小窗口:在窗口增长的过程中,如果传输过程中出现丢包了,说明此时发送的速率接近当前网络的极限,此时会把窗口调整为最初的小窗口并将指数增长的阈值变小,然后继续重复上述的过程。

因此还可以得出一个结论:实际发送的窗口大小不光要考虑接收方的处理能力,还要考虑中间节点的处理能力。

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

七、延时应答

延时应答也是为了增大滑动窗口的大小,从而挺高传输效率而提出的。

延时应答通过在返回ACK应答报文的时候,尽量慢一点,利用拖延出来的一点点时间,让接收方多处理一些数据,这样接收方的接收缓冲区的空间就更大了,下一次就能接收更多的数据。

八、捎带应答

捎带应答是在延迟应答的基础上,引入的进一步提高效率的方式。

延迟应答是让ACK报文传输的时机更慢,我们不仅可以让接收方利用这段时间处理缓存中数据,还可以让接收方做出响应的同时再带上ACK报文(类似将四次握手合并成三次握手)。

之前所提到的四次挥手也有可能变成三次,主要是通过延时应答和捎带应答完成的。在第二挥手的时候进行延时应答,然后跟第三次挥手一起发送给对方,而数据包从两个合并成一个,效率会有明显的提升,因为每次传输数据都会进行封装分用以及传输时延都会花费不少时间。

九、面向字节流——粘包问题

由于TCP是面向字节流的,所接收到的数据包会按照一个字节一个字节的存储在缓存区中,如果我们不认为的进行约定,那么就无法区分一个数据的结尾是哪。

如上所示:

对于发送方来说,发送了3个数据报,AAA为一个应用层数据报,BBB是一个应用层数据报,CCC是一个应用层数据报,但是接收方可区分不了,三个数据报都粘在一起了,很有可能后续会理解错发送方的意思,比如将这三个数据包理解为了AAAB, BBC, CC,就出现了bug。

此时就只能在应用层面来处理这个问题了。如:

  1. 在应用层协议中引入分隔符区分包之间的边界。例如:以\n作为一个数据包的结束标志。

  2. 在应用层协议中引入包长度区分包之间的边界。

十、异常情况处理——心跳包

在实际生活中,会出现许多不可抗力的因素,比如电源被家长关了、网线被人拔了等,不过这些大差不差,可以分为四大类。

1、进程崩溃

当进程崩溃了,进程所持有的PCB中的文件描述符表也就被释放了,即相当于调用了socket.close方法,崩溃的一方在内核中就会发出FIN,就变成了四次挥手了,此时也就和进程的正常退出没啥区别了。

2、主机关机

电脑在正常关机的时候,会先结束掉所有的进程,后续就跟进程崩溃的处理一样了(如果没挥手完也没关系 ,也就演变成了丢了某一次挥手)。

3、主机掉电

如果是台式机的话,一旦拔掉电源,电脑就立马黑屏了,根本不会给操作系统留有反应的空间。此时又分为了两种情况:

a) 如果接收方突然断电了,那么发送方就无法接收到ACK,此时发送方会进行超时重传,如果一直重传失败,就会发送复位报文(RST),尝试重置连接,如果失败了,就会单方面释放连接了。

b)如果发送方突然断电了,接收方无法区分发送方是等一会发送呢,还是不发了,此处就会涉及到"心跳包",接收方就会周期性的给对方发一个不携带任何业务数据的tcp数据报,发起这个这个包的目的,就是为了触发ACK确认对方是否正常工作。

4、网线断开

如果是网线断开的话,其实也跟主机掉电基本类似。

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

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

相关文章

【融合ChatGPT等AI模型】Python-GEE遥感云大数据分析、管理与可视化及多领域应用

随着航空、航天、近地空间遥感平台的持续发展,遥感技术近年来取得显著进步。遥感数据的空间、时间、光谱分辨率及数据量均大幅提升,呈现出大数据特征。这为相关研究带来了新机遇,但同时也带来巨大挑战。传统的工作站和服务器已无法满足大区域…

anaconda配置的环境对应的地址查看,环境安装位置

打开conda指令窗口 这个和上面的都一样,哪个都行 点开后,输入 conda env list 这里显示的就是自己的每个环境对应的地址了

python_4

def reverse(number):a str(number) # 将输入的数字转成字符串print(f"反向输出:{a[::-1]}") # 将字符串通过切片反向输出number int(input("输入整数:")) reverse(number)import mathdef isValid(side1, side2, side3):# 根据"两边之和大于第三边…

安装mmsegmentation默认主分支main

安装时间2024.4.21 mmsegmentation新版本main分支(v1.2.2) 安装过程 conda create --name openmmlab python3.8 -y conda activate openmmlab// 很关键,可以避免mmcv版本问题 pip install torch1.10.1cu113 torchvision0.11.2cu113 torcha…

明日周刊-第7期

转眼间就又快到了五一假期,小长假有什么计划吗。封面配图是杭州高架上的月季花,非常好看。 文章目录 一周热点资源分享言论歌曲推荐 一周热点 鸿蒙系统持续扩大影响力:近期,华为官方宣布广东省已有超过600款应用加入鸿蒙系统&…

文献速递:深度学习胶质瘤诊断---使用深度学习在 MRI 图像中进行低级别胶质瘤的脑肿瘤分割和分级

Title 题目 Brain tumor segmentation and grading of lower-grade glioma using deeplearning in MRI images 使用深度学习在 MRI 图像中进行低级别胶质瘤的脑肿瘤分割和分级 01文献速递介绍 胶质瘤是最常见的脑肿瘤,根据肿瘤的恶性程度和生长速率具有不同的分级…

如何在PostgreSQL中使用pg_stat_statements插件进行SQL性能统计和分析?

文章目录 一、启用pg_stat_statements插件二、查看统计信息三、定期重置统计信息四、注意事项 PostgreSQL中的pg_stat_statements是一个强大的插件,用于追踪执行时间最长的SQL语句。通过它,我们可以获取有关SQL语句执行频率、总执行时间、平均执行时间等…

2024团体程序设计天梯赛L1-104 九宫格

题目链接L1-104 九宫格 #include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int n, mapp[10][10], a[10]; int dx[10]{0, 1, 1, 1, 4, 4, 4, 7, 7, 7}; int dy[10]{0, 1, 4, 7, 1, 4, 7, 1, 4, 7}; b…

HTML:Form表单控件主要标签及属性。name属性,value属性,id属性详解。表单内容的传递流程,get和post数据传递样式。表单数据传递实例

form表单 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head> &…

前端项目的导入和启动

安装依赖 前端安装依赖只需要在控制台执行“npm i”即可。Tips&#xff1a;当我们执行的时候&#xff0c;有时候会很慢。可以考虑使用yarn或者pnpm。然而使用yarn或者pnpm有时候有一些莫名其妙的问题。所以还是得使用npm&#xff0c; 这个时候可以通过更换镜像源为淘宝镜像源。…

递归排列枚举(c++)

全部排列问题 输入 n 输出 1…n 个数的全部排列。全部排列中&#xff0c;数字可以重复 。 例如 输入 3 输出全部排列的结果如下&#xff1a;111、112、113、121、122、123、131、132、133、211、212、213、221、222、223、231、232、233、311、312、313、321、322、323、33…

红外接收器的原理以及在STM32和51单片机中的应用

基本介绍&#xff1a; 红外接收器是一种用于接收红外线信号的装置&#xff0c;常见于各种电子设备中&#xff0c;如电视遥控器、空调遥控器等。它能够接收来自发射器发送的红外信号&#xff0c;并将其转换成电信号&#xff0c;以便设备进行相应的操作。红外接收器通常包含红外光…

C语言语法进阶

条件运算符 条件运算符是 C 语言中唯一的一种三目运算符。三目运算符代表有三个操作数&#xff1b;双目 运算符代表有两个操作数&#xff0c;如逻辑与运算符就是双目运算符&#xff1b;单目运算符代表有一个操作数&#xff0c; 如逻辑非运算符就是单目运算符。运算符也称操作符…

亚马逊---设计安全架构

会从以下三个方面展开&#xff1a; 1、AWS资源访问安全 2、应用程序负载的网络安全 3、云中数据的安全 责任共担模式 就像租房子&#xff08;房东和你的责任&#xff09; AWS资源访问安全 需要掌握以下几点&#xff1a; 1、跨多个账户的访问控制和管理 2、AWS联合访问和身份服…

探索RadSystems:低代码开发的新选择(一)

文章目录 前言一、名词解释1、低代码开发是什么&#xff1f;2、RadSystems Studio是什么&#xff1f; 二、操作步骤1.下载安装2.启动项目 总结 前言 在数字化时代&#xff0c;低代码开发平台成为越来越多企业的首选&#xff0c;因为它们可以大大加速应用程序的开发过程&#x…

ssm068海鲜自助餐厅系统+vue

海鲜自助餐厅系统的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管…

医学图像分割入门-FCN理论与实践

FCN&#xff08;全卷积神经网络&#xff09; 引言 全卷积网络&#xff08;Fully Convolutional Network&#xff0c;简称FCN&#xff09;是一种深度学习模型&#xff0c;专门设计用于图像分割任务。相比于传统的基于全连接层的神经网络&#xff0c;FCN可以接受任意尺寸的输入…

Llama 3 实测效果炸裂,一秒写数百字(附镜像站)

这几天大火的llama 3刚刚在https://askmanyai.cn上线了&#xff01; 玩了一会儿&#xff0c;这个生成速度是真的亚麻呆住。文案写作和代码生成直接爽到起飞&#xff0c;以往gpt要写一两分钟的千字文&#xff0c;llama 3几秒钟就写完了。而且效果甚至感觉更好&#xff1f; 效果惊…

前端表单input的简单使用

1.代码结构介绍 2.实战效果

GARTNER纵横四海 – 2023年LCAP魔力象限图(Magic Quadrant)上各上榜者优势和注意事项

低代码应用平台&#xff08;LCAP-low code application platform&#xff09;通过抽象通用可重复使用软件组件的编码&#xff0c;并将开发人员的工作分配给更接近业务成果的任务&#xff0c;来加速应用程序开发。利用这项研究来比较和对比全球LCAP市场上的上榜企业。 一、市场…