TCP、UDP详解

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不支持(应用程序额外写代码实现)

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

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

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

相关文章

clip系列改进Lseg、 group ViT、ViLD、Glip

Lseg 在clip后面加一个分割head,然后用分割数据集有监督训练。textencoder使用clip,frozen住。 group ViT 与Lseg不同,借鉴了clip做了真正的无监督学习。 具体的通过group block来做的。使用学习的N个group token(可以理解为聚类…

探索音频创作的无限可能——Studio One 5 软件深度解析

Studio One 5 是一款功能强大且备受赞誉的音频制作软件,无论是专业音乐制作人还是业余爱好者,都能在其中找到满足自己需求的强大功能。 对于 Mac 和 Windows 用户来说,Studio One 5 提供了一个直观且友好的操作界面。其简洁明了的布局让用户…

CID引流电商:传统电商破局的新动力

摘要:CID引流电商为传统电商带来破局新机遇,通过跨平台引流、精准定位和高效转化,解决了流量获取难、成本高的问题,提升了销售业绩和市场竞争力。CID引流电商助力传统电商在激烈竞争中保持领先,推动行业持续发展。 随…

pdf转换成cad,这几个cad转换小妙招快码住!

在数字设计领域,PDF(Portable Document Format)和CAD(Computer-Aided Design)文件格式各有其独特之处。PDF常用于文件共享和打印,而CAD则是工程师和设计师们进行精确绘图和建模的必备工具。然而&#xff0c…

elasticsearch重置密码

0 案例背景 Elasticsearch三台集群环境,对外端口为6200,忘记elasticsearch密码,进行重置操作 注:若无特殊说明,三台服务器均需进行处理操作 1 停止es /rpa/bin/elasticsearch.sh stop 检查状态 ps -ef|grep elast…

基于PHP+MySQL组合开发家政预约服务小程序源码系统 带完整的安装代码包以及搭建教程

系统概述 在当今数字化时代,家政服务行业也逐渐融入了科技的力量。为了满足市场需求,我们开发了一款基于 PHPMySQL 组合的家政预约服务小程序源码系统。该系统不仅提供了便捷的家政服务预约功能,还具备完整的安装代码包和详细的搭建教程&…

OpenCloudOS开源的操作系统

OpenCloudOS 是一款开源的操作系统,致力于提供高性能、稳定和安全的操作系统环境,以满足现代计算和应用程序的需求。它结合了现代操作系统设计的最新技术和实践,为开发者和企业提供了一个强大的平台。本文将详细介绍 OpenCloudOS 的背景、特性…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的登山之旅01(100分)- 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 &#x1f…

WPF----进度条ProgressBar(渐变色)

ProgressBar 是一种用于指示进程或任务的进度的控件,通常在图形用户界面(GUI)中使用。它提供了一种视觉反馈,显示任务的完成程度,帮助用户了解任务的进展情况。 基本特性 Minimum 和 Maximum 属性: 这些属…

游戏爱好者将《超级马里奥64》移植到GBA掌机

GBA虽然在当年拥有多款马里奥系列游戏,不过你一定没有想到,N64的《超级马里奥64》也能被移植到这个游戏掌机。近日,一位名为Joshua Barretto的开发者就完成了这一挑战。 大家都知道,《超级马里奥64》于1996年登陆任天堂64主机&am…

maven仓库的作用以及安装 , DEA配置本地Maven

ay12-maven 主要内容 Maven的作用Maven仓库的作用Maven的坐标概念Maven的安装IDEA配置本地Maven 一、maven概述 1.1、项目开发中的问题 1、我的项目依赖一些jar包,我把他们放在哪里?直接拷贝到项目的lib文件夹中?如果我开发的第二个项目还是需要上面…

VR加密方案常见问题有哪些?

在数字化时代,随着虚拟现实(VR)技术的迅速发展与普及,VR视频内容的安全传输成为关注焦点。为保护版权及敏感信息免遭非法复制或篡改,VR视频加密技术显得尤为重要。 首先,高效的加密算法对确保数据安全性至关…

java注解的概念及其使用方法详细介绍

1_注解:概述 路径 什么是注解注解的作用 注解 什么是注解? 注解(Annotation)也称为元数据,是一种代码级别的说明注解是JDK1.5版本引入的一个特性,和类、接口是在同一个层次注解可以声明在包、类、字段、方法、局部变量、方法参…

龙国南方航空滑块acw_v2+cookie+风控处理+type后缀

声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未经许可禁…

【Day03】0基础微信小程序入门-学习笔记

文章目录 视图与逻辑学习目标页面导航1. 声明式导航2. 编程式导航3. 导航传参 页面事件1. 下拉刷新2. 上拉触底3.扩展-自定义编译模式 生命周期1. 简介2. 生命周期函数3. 应用的生命周期函数4. 页面生命周期函数 WXS脚本1. 概述2. 基础语法3. WXS的特点4. 使用WXS处理手机号 总…

计算机网络:如何隐藏真实的IP和MAC地址?

目录 一、什么是MAC地址二、什么是IP地址三、如何隐藏真实的MAC地址四、如何隐藏真实的IP地址 一、什么是MAC地址 MAC地址,全称为媒体访问控制地址(Media Access Control Address),是一种用于网络通信的唯一标识符。它是由IEEE 8…

深入解析Java和Go语言中String与byte数组的转换原理

1.Java String与byte[]互相转换存在的问题 java中,按照byte[] 》string 》byte[]的流程转换后,byte数据与最初的byte不一致。 多说无益,上代码,本地macos机器执行,统一使用的UTF-8编码。 import java.nio.charset.S…

【最佳实践】前端如何搭建自己的cli命令行工具,让自己编码的时候如虎添翼

作为前端开发人员,搭建自己的前端CLI工具是一个有趣且有意义的事情。以下是一篇详细的教程,包括使用场景和案例。 使用场景 假设你是一个前端团队的一员,需要频繁地在不同的项目中执行一些标准化的任务,比如: 根据模…

一次tcpdump抓包过程

#查询网卡 tcpdump -D # 监听 21100 端口 网卡ens192 (不知道网卡,可以直接不输入 -i 网卡)TCP数据,等待一段时间,执行CtrlC,终止程序 tcpdump -x -s 0 -w /tmp/123.dump -i ens192 -p tcp port 21100 #…

充电桩小程序:引领未来,携手共创绿色充电新纪元

着新能源汽车市场的迅猛增长,充电桩行业正迎来前所未有的发展机遇。然而,在这个充满竞争和机遇并存的时代,如何快速、高效地满足用户需求,成为充电桩行业老板们关注的焦点。为此,我们推出了全新的充电桩小程序&#xf…