本文为社区首发签约文章,14天内制止转载,14天后未获授权制止转载,侵权必究!

话说,UDP比TCP快吗?

信任就算不是八股文老手,也会下意识的脱口而出:”“。

这要追问为什么,估量咱们也能说出个大约。

动图图解 | UDP就一定比TCP快吗?

但这也让人猎奇,用UDP就必定比用TCP快吗?什么情况下用UDP会比用TCP慢?

咱们今天就来聊下这个论题。


运用socket进行数据传输

作为一个程序员,假设咱们需求在A电脑的进程发一段数据到B电脑的进程,咱们一般会在代码里运用socket进行编程。

socket就像是一个电话或许邮箱(邮政的信箱)。当你想要发送音讯的时分,拨通电话或许将信息塞到邮箱里,socket内核会主动完成将数据传给对方的这个进程。

依据socket咱们能够挑选运用TCP或UDP协议进行通讯。

关于TCP这样的牢靠性协议,每次音讯宣布后都能明确知道对方收没收到,就像打电话相同,只要”喂喂”两下就能知道对方有没有在听。

而UDP就像是给邮政的信箱寄信相同,你寄出去的信,根本就不知道对方有没有正常收到,丢了也是有或许的。

这让我想起了大约17年前,其时还没有现在这么发达的网购,想买一本《掌机迷》杂志,还得往信封里塞钱,然后一等便是一个月,好几次都置疑信是不是丢了。我至今印象深入,由于那是我和我哥攒了良久的钱。。。


回到socket编程的论题上。

创立socket的方式就像下面这样。

fd = socket(AF_INET, 具体协议,0);

注意上面的”具体协议“,假如传入的是SOCK_STREAM,是指运用字节流传输数据,说白了便是TCP协议

动图图解 | UDP就一定比TCP快吗?

假如传入的是SOCK_DGRAM,是指运用数据报传输数据,也便是UDP协议

动图图解 | UDP就一定比TCP快吗?

回来的fd是指socket句柄,能够理解为socket的身份证号。经过这个fd你能够在内核中找到唯一的socket结构。

假如想要经过这个socket发音讯,只需求操作这个fd就行了,比方执行 send(fd, msg, ...),内核就会经过这个fd句柄找到socket然后进行发数据的操作。

假如一切顺利,此刻对方执行接纳音讯的操作,也便是 recv(fd, msg, ...),就能拿到你发的音讯。

动图图解 | UDP就一定比TCP快吗?

关于反常情况的处理

但假如不顺利呢?

比方音讯发到一半,丢包了呢?

丢包的原因有许多,之前写过的《用了TCP协议,就必定不会丢包吗?》有具体聊到过,这儿就不再展开。

那UDP和TCP的情绪就不太相同了。


UDP表示,”哦,是吗?然后呢?关我x事”

TCP情绪就截然相反了,”啊?那可不行,是不是我发太快了呢?是不是链路太堵被别人影响到了呢?不过你放心,我肯定给你补发”

TCP老实人石锤了。咱们来看下这个老实人在背面都默默做了哪些工作。

重传机制

关于TCP,它会给宣布的音讯打上一个编号(sequence),接纳方收到后回一个承认(ack)。发送方能够经过ack的数值知道接纳方收到了哪些sequence的包。

假如长时间等不到对方的承认,TCP就会重新发一次音讯,这便是所谓的重传机制

动图图解 | UDP就一定比TCP快吗?


流量操控机制

但重传这件事自身对功能影响是比较严重的,所以是下下策

所以TCP就需求思考有没有方法能够尽量防止重传

由于数据发送方和接纳方处理数据才能或许不同,因而假如能够依据两边的才能去调整发送的数据量就好了,所以就有了发送和接纳窗口,基本上从姓名就能看出它的作用,比方接纳窗口的巨细便是指,接纳方当前能接纳的数据量巨细发送窗口的巨细就指发送方当前能发的数据量巨细。TCP依据窗口的巨细去操控自己发送的数据量,这样就能大大削减丢包的概率。

动图图解 | UDP就一定比TCP快吗?


滑动窗口机制

接纳方的接纳到数据之后,会不断处理,处理才能也不是一成不变的,有时分处理的快些,那就能够收多点数据,处理的慢点那就希望对方能少发点数据。究竟发多了就有或许处理不过来导致丢包,丢包会导致重传,这可是下下策。因而咱们需求动态的去调节这个接纳窗口的巨细,所以就有了滑动窗口机制

看到这儿咱们或许就有点迷了,流量操控和滑动窗口机制形似很像,它们之间是啥联系?我总结一下。其完成在TCP是经过滑动窗口机制来完成流量操控机制的

动图图解 | UDP就一定比TCP快吗?


拥塞操控机制

但这还不够,有时分发生丢包,并不是由于发送方和接纳方的处理才能问题导致的。而是跟网络环境有关,咱们能够将网络想象为一条公路。马路上或许堵满了别人家的车,只留下一辆车的空间。那就算你家有5辆车,目的地也正好有5个停车位,你也没方法一起悉数一起上路。所以TCP希望能感知到外部的网络环境,依据网络环境及时调整自己的发包数量,比方马路只够两辆车跑,那我就只发两辆车。但外部环境这么杂乱,TCP是怎样感知到的呢?

TCP会先慢慢试探的发数据,不断加码数据量,越发越多,先发一个,再发2个,4个…。直到出现丢包,这样TCP就知道现在当前网络大约吃得消几个包了,这既是所谓的拥塞操控机制

不少人会疑问流量操控和拥塞操控的联系。我这儿小小的总结下。流量操控针对的是单个衔接数据处理才能的操控,拥塞操控针对的是整个网络环境数据处理才能的操控。

动图图解 | UDP就一定比TCP快吗?


分段机制

但上面说到的都是怎样下降重传的概率,似乎重传这个工作便是无法防止的,那假如确实发生了,有没有方法下降它带来的影响呢?

有。当咱们需求发送一个超大的数据包时,假如这个数据包丢了,那就得重传相同大的数据包。但假如我能将其分红一小段一小段,那就算真丢了,那我也就只需求重传那一小段就好了,大大减小了重传的压力,这便是TCP的分段机制

而这个所谓的一小段的长度,在传输层叫MSSMaximum Segment Size),数据包长度大于MSS则会分红N个小于等于MSS的包。

动图图解 | UDP就一定比TCP快吗?

而在网络层,假如数据包还大于MTU(Maximum Transmit Unit),那还会持续分包。

动图图解 | UDP就一定比TCP快吗?

一般情况下,MSS=MTU-40Byte,所以TCP分段后,到了IP层大约率就不会再分片了

动图图解 | UDP就一定比TCP快吗?


乱序重排机制

已然数据包会被分段,链路又这么杂乱还会丢包,那数据包乱序也就显得不奇怪了。比方发数据包1,2,3。1号数据包走了其他网络路径,2和3数据包先到,1数据包后到,所以数据包次序就成了2,3,1。这一点TCP也考虑到了,依靠数据包的sequence,接纳方就能知道数据包的先后次序。

后发的数据包先到是吧,那就先放到专门的乱序行列中,等数据都到齐后,重新整理好乱序行列的数据包次序后再给到用户,这便是乱序重排机制

动图图解 | UDP就一定比TCP快吗?


衔接机制

前面说到,UDP是无衔接的,而TCP是面向衔接的。

这儿说到的衔接到底是啥?

TCP经过上面说到的各种机制完成了数据的牢靠性。这些机制背面是经过一个个数据结构来完成的逻辑。而为了完成这套逻辑,操作系统内核需求在两头代码里保护一套杂乱的状态机(三次握手,四次挥手,RST,closing等反常处理机制),这套状态机其实便是所谓的”衔接”。这其实便是TCP的衔接机制,而UDP用不上这套状态机,因而它是”无衔接”的。


网络环境链路很长,还杂乱,数据丢包是很常见的。

咱们平常用TCP做各种数据传输,完全对这些工作无感知。

哪有什么年月静好,是TCP替你负重前行。

这便是TCP三大特性”面向衔接、牢靠的、依据字节流”中”牢靠“的意义。

不信你改用UDP试试,丢包那便是真丢了,丢到你置疑人生。


用UDP就必定比用TCP快吗?

这时分UDP就不服了:”正由于没有这些杂乱的TCP牢靠性机制,所以我很快啊

嗯,这也是大部分人以为UDP比TCP快的原因。

实际上大部分情况下也确实是这样的。这话没毛病。


那问题就来了。

有没有用了UDP但却比TCP慢的情况呢?

其实也有。

在回答这个问题前,我需求先说下UDP的用处

实际上,大部分人也不会测验直接拿裸udp放到生产环境中去做项目。

那UDP的价值在哪?

在我看来,UDP的存在,本质是内核提供的一个最小网络传输功能

许多时分,咱们尽管号称自己用了UDP,但实际上都很忌惮它的丢包问题,所以大部分情况下都会在UDP的基础上做各种不同程度的应用层牢靠性保证。比方王者农药用的KCP,以及最近很火的QUIC(HTTP3.0),其实都在UDP的基础上做了重传逻辑,完成了一套相似TCP那样的牢靠性机制。

教科书上最爱提UDP适合用于音视频传输,由于这些场景答应丢包。但其实也不是什么包都能丢的,比方重要的要害帧啥的,该重传还得重传。除此之外,还有一些乱序处理机制。举个比方吧。

打音视频电话的时分,你或许遇到过丢失中心某部分信息的情况,但应该从来没遇到过乱序的情况吧。

比方对方打网络电话给你,说了:”我好想给小白来个点赞在看!

这时分网络信号欠好,你或许会听到”我….点赞在看”。

但却从来没遇到过”在看小白好想赞”这样的乱序场景吧?

所以说,尽管挑选了运用UDP,但一般仍是会在应用层上做一些重传机制的

所以问题就来了,假如现在我需求传一个特别大的数据包

TCP里,它内部会依据MSS的巨细分段,这时分进入到IP层之后,每个包巨细都不会超越MTU,因而IP层一般不会再进行分片。这时分发生丢包了,只需求重传每个MSS分段就够了。

动图图解 | UDP就一定比TCP快吗?

但关于UDP,其自身并不会分段,假如数据过大,到了IP层,就会进行分片。此刻发生丢包的话,再次重传,就会重传整个大数据包

动图图解 | UDP就一定比TCP快吗?

关于上面这种情况,运用UDP就比TCP要慢

当然,处理起来也不杂乱。这儿的要害点在所以否完成了数据分段机制,运用UDP的应用层假如也完成了分段机制的话,那就不会出现上述的问题了


总结

  • TCP为了完成牢靠性,引入了重传机制、流量操控、滑动窗口、拥塞操控、分段以及乱序重排机制。而UDP则没有完成,因而一般来说TCP比UDP快。
  • TCP是面向衔接的协议,而UDP是无衔接的协议。这儿的”衔接“其实是,操作系统内核在两头代码里保护的一套杂乱状态机。
  • 大部分项目,会在依据UDP的基础上,模仿TCP,完成不同程度的牢靠性机制。比方王者农药用的KCP其实就在依据UDP在应用层里完成了一套重传机制。
  • 关于UDP+重传的场景,假如要传超大数据包,并且没有完成分段机制的话,那数据就会在IP层分片,一旦丢包,那就需求重传整个超大数据包。而TCP则不需求考虑这个,内部会主动分段,丢包重传分段就行了。这种场景下,其实TCP更快。

最终

最近原创更文的阅读量稳步下跌,思前想后,夜里辗转反侧。

我有个不成熟的恳求。

动图图解 | UDP就一定比TCP快吗?

脱离广东好长时间了,良久没人叫我靓仔了。

咱们能够在评论区里,叫我一靓仔吗?

我这么仁慈质朴的愿望,能被满足吗?

假如真实叫不出口的话,能帮我点下关注和右下角的点赞+收藏吗?


别说了,一起在知识的海洋里呛水吧