TCP、UDP详解

news2024/7/4 5:53:38

TCP和UDP是传输层的两个重要协议,也是面试中经常会被问到的,属于面试高频点。今天,我们来学习这两个协议。

1.区别

1.1 概括

TCP:有连接,可靠传输,面向字节流,全双工

UDP:无连接,不可靠,面向数据报,全双工

1.2 详解

1.TCP是有连接的,UDP是无连接的

连接是抽象的概念,本质上是建立连接的双方,各自保存对方的信息

两台计算机建立连接,就是彼此保存了对方的关键信息

TCP想要通信,就需要建立连接,做完之后,才能后续通信。至于连接如何建立,不需要代码干预,是系统内核自动负责完成的。

对于应用程序来说,客户端这边,主要是要发起“建立连接”动作;服务器这边,主要是把建立好的连接从内核中拿到应用程序里~

如果有客户端,和服务器建立连接,这个时候服务器的应用程序是不需要做出任何操作(也没有任何感知的),内核直接就完成了,建立连接的过程(三次握手),完成流程之后,就会在内核的队列中(这个队列是每个serverSocket都有一个这样的队列)排队。

应用程序要想和这个客户端进行通信,就需要通过一个accept方法,把内核队列已经建立好的连接对象,拿到应用程序中。

即一个典型的生产者-消费者模型。

UDP想要通信,直接发送数据即可,不需要征得对方同意,UDP自身也不会保存对方的信息

2.TCP是可靠传输,UDP是不可靠传输的

网络上进行通信,A-> B发送一个消息,这个消息是不可能做到100%送到的

TCP就内置了可靠传输机制,UDP就没有内置可靠传输。

A -> B 发消息,消息是不是到达B这一方,A自己能感知到,进一步的,就可以在发送失败的时候采取一定的措施(尝试重传之类的)

可靠传输需要付出代价:a.机制更复杂  b.传输效率会降低

3.TCP是面向字节流的,UDP是面向数据报的

TCP和文件一样,以字节位单位来进行传输

UDP则是按照数据报为单位,来进行传输的(UDP数据报是有严格的格式的)

4.TCP和UDP都是全双工的

一个信道,允许双向通信,就是全双工

一个信道,允许单向通信,就是半双工

2.TCP

2.1 内容

2.2 可靠传输

常见面试题:

TCP是如何保证可靠传输的?

通过确认应答为核心,借助其他机制辅助,最终完成可靠传输

2.2.1 确认应答

发送方,把数据发给接收方之后,接收方收到数据就会给发送方返回一个应答报文

发送方,如果收到这个应答报文了,就知道自己的数据是否发送成功

2.2.2 超时重传

如果网络传输过程中,出现丢包了,发送包,势必就无法收到ACK了

由于丢包是一个“随机”的事件,因此在TCP传输过程中,丢包就存在两种情况:

1.传输的数据丢了

2.返回的ACK丢了

无论出现上述两种情况,发送方都会采取统一的措施,就是“重传”

发送方,何时重传?等待时间

发送方,发出数据之后,会等待一段时间,如果这个时间之内,ack来了,此时就自然视为数据到达

如果达到这个时间之后,数据还没到,就会触发重传机制~

超过等待时间,再重传~

第二次重传后的等待时间会比第一次时间延长,但延长也不是无限制延长,重传若干次后,时间拉长到一定程度,认为数据再重传也没有用了,就放弃tcp连接(准确来说就是会触发tcp的重置连接操作)

TCP会有一个“接收缓冲区”就是一个内存空间,会保存当前已经收到的数据,以及数据的序号

接收方如果发现,当前发送方发来的数据,是已经再接收缓冲区中存在的(收到过的重复数据了),接收方就会直接把这个后来的数据给丢弃掉,确保应用程序进行read的时候,读到的是只有一个数据

2.2.3 连接管理

建立连接 + 断开连接

面试中最经典的问题:三次握手 + 四次挥手

建立连接

三次握手

tcp这里的握手,也就是给对方传输一个简短的,没有业务数据的数据包,通过这个数据包,来唤起对方的注意,从而触发后续的操作(握手这个操作,不是TCP独有的,甚至不是网络通信独有的,计算机中很多的操作,都会涉及到握手)

TCP的三次握手,TCP在建立连接的过程中,需要通信双方进行“打三次招呼”才能够完成连接建立的

问:三次握手是要解决什么问题?

答:三次握手核心作用一:

投石问路,确认当前网络是否是畅通的

三次握手核心作用二:

能够发送方和接受党都能确认自己的接收能力和发送能力均正常

三次握手核心作用三:

让通信双方,在通信过程中,针对一些重要的参数,进行协商

问:四次握手可以吗?两次握手可以吗?

答:四次:可以,但没必要

两次:不可以,不能达到双方都知道信息的过程

断开连接

四次挥手

为什么中间两次不能像建立连接一样合并为一步?

不一定

不能合并的原因:ACK和第二个FIN的触发时机是不同的

ACK是内核响应的,B收到FIN,就会立即返回ACK

第二个FIN是应用程序的代码触发,B这边调用了close方法,才会触发FIN

是否意味着,如果这这边代码close没写/没执行到,是不是第二个FIN就一直发不出去?(有可能的)

如果是正常的四次挥手,正常的流程断开的连接

如果是不正常的挥手(没有挥完四次),异常的流程断开连接(也是存在的)

三次握手ACK和第二个syn都是内核触发的,同一个时机,可以合并

可以合并的情况:TCP还有一个机制,延迟应答,能够拖延ACK的回应时间,一旦ACK滞后了,就有机会和下一个FIN一起合并

哪一方,主动断开连接,哪一方就会进入TIME_WAIT

TIME_WAIT状态的主要存在的意义,就是为了防止最后一个ACK丢失,留下的后手

如果最后一个ACK丢了,站在B的角度,B就会触发超时重传,重新把刚才的FIN给传一遍

如果刚才A没有TIME_WAIT状态,就意味着A这个时候就已经真的释放连接了,此时重传的FIN也就没人能处理,没人能返回ACK了,B也就永远收不到ACK了

A这边使用TIME_WAIT状态进行等待,等待的这个时间,就会为了处理后续B重传的FIN

此时如果有重传的FIN来了,就可以继续返回ACK了,B这边的重传才有意义

TIME_WAIT等待多久呢?

假设网络上两个节点通信消耗的最大等待时间为MSL,此时的TIME_WAIT的时间就是2MSL (已经是上限了,绝大部分的数据包不会达)

2.2.4 滑动窗口

提高效率

TCP的可靠传输,是会影响传输的效率的

滑动窗口,就让可靠传输性能的影响,更小一些

TCP只要引入了可靠传输,传输效率是不可能超过没有可靠性的UDP的

TCP这里的“效率机制”都是为了让影响更小,缩小和UDP的差距

批量传输数据,不等ack回来,直接再发下一个数据

批量传输,也不是“无限的”传输

批量传输也是存在一定的上限的,达到上限之后,再统一等待ack

不等待的情况,批量最所发多少数据,这个数据量,称为“窗口大小”

当前A->B是批量的发了四份数据

此时B也要给A回应四组ACK,此时A已经达到窗口大小,再收到ACK之前,不能继续往下发了

需要等待有ACK回来了之后,才能继续往下发。

可以不需要一次等待四个ACK全部回来之后才能继续发,而是回来一个ack,就立即继续发一个

窗口越大,等待的ack越多,此时传输效率也就越高

情况一:ack丢了

这种情况,不需要任何重传,没事了

确认信号,表示的含义是,当前序号之前的数据,已经确认收到了

下一个你应该从确认序号这里,继续发送

例如:如果1001这个ACK丢了,但是2001ACK到了,则证明2001之前的数据都已经确认传输成功了,涵盖了1001的情况

情况二:数据包丢了

主机A就需要知道是哪个数据丢了,主机B也就得告诉A是哪个数据丢了。

主机A看到了B这边连续的几个ack,都是再索要1001,A就知道了,1001这个数据就是丢了,就重传了1001

1001-2000重传之后,顺利到达B索要的就是7001

上述的重传过程,并没有额外的冗余操作,哪个数据丢了,就重传哪个,没丢的数据就不需要重传,整个过程都是比较快速的

如果通信双方,传输数据的量比较小,也不频繁,就仍然是普通的确认应答和超时重传。

如果通信双方,传输数据量更大,也比较频繁,就会进入到滑动窗口模式,按照快速重传的方式处理。

通过滑动窗口的方式传输数据,效率是会提升的

窗口越大,传输效率就越大(一份时间,等待的ack更多了,总的等待时间更少了)

当然,滑动窗口也不是设置越大越好

如果传输的速度太快,就可能会使接收方,处理不过来了,此时,接收方也会出现丢包,发送方还得重传。

2.2.5 流量控制

站在接收方的角度,反向制约发送方的传输效率

考虑接收方的处理能力

发送方发送的速率,不应该超过接收方的处理能力

可以根据缓冲区剩余空间大小来判断消费者处理速度

把剩余缓冲区返回给发送方,发送方根据改缓冲区大小发送数据

窗口探测包:并不携带具体的业务数据,只是为了触发ack,为了查询当前接收方这边的接收缓冲区剩余空间。

2.2.6 拥塞控制

不仅仅是接收方,还有整个通信的路径

关键问题:接收方的处理能力,很方便进行量化

但是中间节点,结构更复杂,更难以直接的进行量化,因此可以通过“实验”的方式,来找到一个合适的值

让A先按照比较低的速度(小的窗口)来发送数据

如果数据传输的过程非常顺利,没有丢包,再尝试使用更大的窗口,更高的速度进行发送(一点一点变化)

随着窗口大小不停的增大,达到一定的程度,可能中间节点就会出现问题了,此时这个节点就可能出现丢包

发送方发现丢包了,就把窗口大小调整小,此时如果还是继续丢包,就继续缩小,如果不丢包了,就继续尝试变大

在这个过程中,发送发不断调整窗口大小,逐渐达到“动态平衡”

最终时机发送的窗口大小,是取流量控制和拥塞控制中的窗口的较小值

2.2.7 延时应答

A把数据传给B,B就立即返回ack给A(正常)

也有时候,A传输给B,此时B等一会再返回给ack给A(延时应答)

本质上也是为了提升传输效率

延时返回ack,给接收方更多的时间,来读取接收缓冲区的数据

此时接收方读了这个数据之后,缓冲区剩余空间,变大了,返回的窗口大小也就更大了

2.2.8 捎带应答

在延时应答的基础上,进一步的提升效率

网络通信中,往往是这种“一问一答”这样的通信模型

ack也是内核立即返回的,response则是应用程序代码来返回的,这两者的时机是不同的

由于tcp引入了延时应答,上面的ack不一定是立即返回,可能要等一会

在等一会的过程中,B就刚好把response给计算好了,计算好了之后,就会把response返回,与此同时顺便就把刚才要返回的ack也带上了,两个数据就合并成了一个数据,此时就可以得到更高效的效果

2.2.9 面向字节流

这里有一个最重要的问题,粘包问题(不是tcp独有的,而是面向字节流的机制都有类似的情况)

此处“包”应用层数据包,如果同时有多个应用层数据包被传输过去,此时就容易出现粘包问题

目前,接收缓冲区中,这三个应用层数据包的数据,就是以字节的形式紧紧挨在一起的

接收方的应用程序,读取数据的时候,可以一次读一个字节,也可以读两个字节也可以读N个字节……

但是最终的目标是为了得到完整的应用层数据包,B应用程序,就不知道,缓冲区里的数据,从哪里到哪里是一个完整的应用数据包了

相比之下,像UDP这样的面向数据报的通信方式,就没有上述问题

UDP的接收缓冲区中,相当于是一个一个的DatagramPacket对象,应用程序读的时候,就明确知道哪里到哪里是一个完整的数据。

如何解决粘包问题?

核心思想:通过定义好应用层协议,明确应用层数据包之间的边界

1.引入分隔符

例如,可以使用\n作为分隔符

aaa\n

bbb\n

ccc\n

2.引入长度

3aaa

4bbbb

3ccc

自定义应用层协议的格式

xml,json,protobuffer,本身都是明确了包的边界的

2.2.10 异常情况的处理

如果在tcp的使用中出现了意外,会如何处理?

1.进程崩溃

(本质上是进程没了,异常终止了。文件描述符表,也就释放了,相当于调用socket.close(),此时就会触发FIN,对方收到之后,自然也就返回FIN和ACK,这边再进行ACK,即正常的四次挥手断开连接的流程)

TCP的连接,可以独立于进程存在(进程没了,TCP连接不一定没)

2.主机关机(正常关机)

进行关机的时候,就是会触发强制终止进程的操作,相当于1,此时就会触发FIN,对方收到之后就会返回FIN和ACK,此时不仅仅是进程没了,整个系统也可能关闭了,如果在系统关闭之前,对端返回的ACK和FIN到了,此时系统还是可以返回ACK,进行正常的四次挥手。但如果系统已经关闭了,ACK和FIN迟到了,无法进行后续ACK的响应,站在对端的角度,对端以为是自己的FIN丢包了,重传FIN,重传几次都没有响应,自然就会放弃连接(把持有的对端的信息就删了)。

3.主机掉电(非正常)

此时,就是一瞬间的事情,来不及杀进程,也来不及发送FIN,主机就直接停机了,站在对端的角度,对端不一定知道这个事情

如果对端是在发送数据(接收方掉电),发送的数据就一直会等待ACK ,触发超时重传,触发TCP连接重置功能,发起“复位报文段”,如果复位报文段发过去之后,也没有效果,此时就会释放连接了

RST复位报文段

如果对端是在接收数据(发送方掉电),对端还在等待数据到达…..等了半天没消息,此时其实是无法区分,是对端没发消息,还是对方挂了

TCP中提供了心跳包机制(形象的比喻),即接收方也会周期性的给发送方发送一个特殊的,不携带业务数据的数据包,并且期望对方返回一个应答,如果对方没有应答,并且重复了多次之后,仍然没有,就视为对方挂了,此时就可以单方面释放连接了。

4.网线断开

和主机掉电非常类似

当前A给B发送数据,一旦网线断开

A就相当于会触发超时重传 -> 连接重置 ->单方面释放连接

B就会触发心跳包 -> 发现对端没响应 -> 单方面释放连接

3.对比

TCP和UDP之间的对比

TCP优势在于可靠传输,更适用绝大部分场景

UDP优势在于高效率,更适用于“可靠性不敏感,性能敏感”场景

局域网内部(同一个机房)的主机之间通信

如果要传输比较大的数据包,TCP更优先(UDP有64kb的限制)

如果要进行“广播传输”,优先考虑UDP,UDP天然支持广播,TCP不支持(应用程序额外写代码实现)

有一种特殊的场景,需要把数据发给局域网的所有机器,这个情况就是广播

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

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

相关文章

vue3 【提效】自动注册组件 unplugin-vue-components 实用教程

还在为每次都要导入组件而烦恼吗 &#xff1f; // 每次都需手动导入组件 import webName from /components/webName.vue用 unplugin-vue-components 来帮你吧&#xff0c;以后组件直接拿来用即可&#xff0c;无需再导入啦 &#xff01; <webName />使用流程 1. 安装 un…

nodejs安装(2024最最最最新版)

node官网 Index of /dist/https://nodejs.org/dist/ 选择版本 我比较喜欢16.20.1或者是14.16.1,这两个版本简直天下无敌了 下一步 选择这个,下载下来一个文件 一直点击下一步,就安装成功了 可能遇见的问题 1.安装了node,为什么不生效还是以前自己电脑安装的版本? 答: 可…

第四天 怎么又迟到了呀 哎啥时候来准时上个课呀

泛型编程 Traits实现&#xff0c;是什么 泛型编程&#xff08;Generic Programming&#xff09;是一种通过编写与特定类型无关的代码来实现代码复用和抽象的编程范式。 在C中&#xff0c;模板&#xff08;Templates&#xff09;是实现泛型编程的主要手段。 Traits&#xff0…

计算机组成原理——系统总线

题目:计算机使用总线结构便于增减外设,同时__C____。 A.减少了信息传送量 B.提高了信息传输速度 C.减少了信息传输线的条数 1. 总线的分类 1.1. 片内总线 芯片内部的总线 在CPU芯片内部,寄存器与寄存器之间、寄存器与逻辑单元ALU之间 1.1.1. 数据总线 双向传输总线 数…

欢乐钓鱼大师攻略:卡鱼骨、典藏鱼、藏宝图怎么钓?

《欢乐钓鱼大师》是一款以钓鱼为核心玩法的休闲模拟手游&#xff0c;通过逼真的画面和丰富的钓鱼体验吸引了大量玩家。本文将为你详细介绍这款游戏的亮点、常见问题以及一些实用的游戏技巧&#xff0c;帮助你在《欢乐钓鱼大师》中获得更愉快的游戏体验。 辅助工具 1. 辅助工具…

OSM数据导入至PostgreSQL

好几年没写博客了&#xff0c;最近博士小论文扩展准备添加个路网数据增加定位准确性 用的读取代码是github上的代码&#xff0c;使用openstreet数据。 1&#xff0c;从BBBbike划定区域下载路网数据&#xff0c;BBBike extracts OpenStreetMap (OSM, Garmin, Shapefile etc.) …

1.1电路模型

1.1电路模型 任何实际电路由以下三部分组成&#xff1a; ①提供电能的能源 – 电源 ②用电装置 – 负载 ③传输电能的金属连线 – 导线 实际电路完成的功能&#xff1a;主要有以下两个方面&#xff1a; &#xff08;1&#xff09;进行能量的产生、传输和转换。&#xff08;如…

C++之STL(十)

1、适配器 2、函数适配器 #include <iostream> using namespace std;#include <algorithm> #include <vector> #include <functional>bool isOdd(int n) {return n % 2 1; } int main() {int a[] {1, 2, 3, 4, 5};vector <int> v(a, a 5);cou…

boss直聘招聘数据爬取及可视化分析2.0

boss直聘招聘数据爬取及可视化分析2.0 一、需求介绍二、完整代码2.1 爬虫代码2.2 数据可视化模块一、需求介绍 笔者在前两篇介绍boss直聘招聘数据爬取和可视化分析的博客的基础上,对代码和功能进行了完善。在数据爬取的模块,代码更加简洁易懂,且性能更加稳定;在数据可视化…

linux基于wifi,Xshell的远程连接

最近有个比赛&#xff0c;要使用ros小车但是系统是ubuntu20.04无桌面系统刚开始接触linux的我啥都不会&#xff0c;就一个简单的连接wifi都搞了3天才搞通。再此进行一个总结。参考博客原文链接&#xff1a;https://blog.csdn.net/qq_51491920/article/details/126221940 一、什…

2024年全国青少年信息素养大赛图形化编程复赛样题_6547网

第 1 题 问答题 【编程实现】 按空格键随机切换背景&#xff0c;让背景对应的角色造型显示在舞台上。 【具体要求】 对角色编程&#xff0c;当按下空格键时&#xff0c;背景随机切换&#xff1b; 角色切换成对应的造型显示在舞台上&#xff1b; 角色说“我是”和它的造…

这谁顶得住啊!AI绘画模型竟然可以画出质量逼真的黑丝!

今天看到一个有趣的AI绘画玩法&#xff0c;用SD画黑丝&#xff01;话不多说&#xff0c;开始今天的实战演练。 首先做好准备工作&#xff1a;部署好本地Stable Diffuison 然后就轮到今天的主角上场了 黑丝Lora模型&#xff1a;perfectpantyhose 这是一款叫perfectpantyhose…

使用容器配置文件构建任意应用镜像_并将应用镜像推送到公共仓库共享_应用分享与启动---分布式云原生部署架构搭建012

上面我们编写好了应用,并且,安装好了redis 现在我们把应用打包成镜像. 以前是这样做的,不方便,因为需要在服务器上,安装jdk什么的,现在有了 镜像就不用,给服务器安装镜像什么的了 以后所有机器都安装docker以后,就直接运行就可以了 首先看一下,安装java应用,需要 用到openjd…

项目经理必读:三步走实现项目高效管理

一个项目的成功往往取决于项目管理能力的高低。若管理不当&#xff0c;易导致团队成员间的推诿和抱怨&#xff0c;且项目团队还可能面临成员对目标不明确、信息不透明、进度难以跟踪等问题。作为项目经理&#xff0c;掌握有效的项目管理策略至关重要。 一、精细化的目标拆解 …

idea的代码提示插件使用记录

安装ai插件卸载之后&#xff0c;偶尔还是idea一直占用100%&#xff0c;将idea缓存全清理了&#xff0c;重新生成之后就正常了 idea官方插件 下面几个感觉…基本没有感觉 按行提示的偶尔有提示&#xff0c;&#xff08;cpu占用不小&#xff0c;提示不强&#xff09; 缺点&am…

Node版本管理工具 fnm 安装使用

fnm 是一个基于 Rust 开发的 Node 版本管理工具&#xff0c;它的目标是提供一个快速、简单且可靠的方式来管理 Node.js 的不同版本。同时&#xff0c;它是跨平台的&#xff0c;支持 macOS、Linux、Windows。&#x1f680; Fast and simple Node.js version manager, built in R…

无线通讯几种常规天线类别简介

天线对于无线模块来说至关重要&#xff0c;合适的天线可以优化通信网络&#xff0c;增加其通信的范围和可靠性。天线的选型对最后的模块通信影响很大&#xff0c;不合适的天线会导致通信质量下降。针对不同的市场应用&#xff0c;天线的材质、安置方式、性能也大不一样。下面简…

Springboot集成JWT实现登录注册

记录一下使用Springboot集成JWT实现登录注册&#xff0c;以后有用到直接copy即可。 整体流程 依赖 <!--引入jwt--> <dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.4.0</version> &l…

NodeJS替旅系统-计算机毕业设计源码27907

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。替旅系统设计&#xff0c;主要的模块包括查看后台首页、轮播图&#xff08;轮播图管理&#xff09;、公告管理&#xff08;公告栏&#xff09;、…

TextRank 算法

第1关&#xff1a;Jieba 在关键词提取中的应用 任务描述 本关任务&#xff1a;根据本关所学有关使用 Jieba 库进行关键词提取的知识&#xff0c;编写使用 Jieba 模块进行关键词提取的程序&#xff0c;并通过所有测试用例。 相关知识 为了完成本关任务&#xff0c;你需要掌握…