生活工程体验信仰哲学精神
投稿投诉
精神世界
探索历史
哲学文学
艺术价值
信仰创造
境界审美
体验技术
技能工具
工程信息
医学生产
生活运用
操作能力

UDP为什么没有epoll

5月9日 眉梢欢投稿
  首先,讲讲UDP编程为什么不需要用到系统的epoll函数,
  RichardStevens在不朽的经典《Unix网络编程卷一》中已经说了:大多数情况下,TCP服务器是并发的,UDP的服务器是迭代的。
  上面这句话可能不太容易理解。
  我基于自己的理解,用大白话跟大家讲,为什么UDP用不到epoll的系统函数。
  首先借用一句话,内核不是解决方案,而是问题所在。
  linux操作系统为什么需要提供epoll函数,在epoll之前还有selectpoll函数。这些函数是干什么的。
  首先,多路复用这个词是针对面向链接协议的说法,一个客户端连接就是一路。
  但是实际上,在IP层,或者说在网络底层,根本就没有什么多路,只有一路。没错,只有一路。
  TCP服务器一般是这样的流程,一个线程处理一个客户端连接:
  C音视频开发学习资料:点击领取音视频开发(资料文档视频教程面试题)(FFmpegWebRTCRTMPRTSPHLSRTP)
  创建服务器描述符sfdsfdsocket()把服务器fd绑定地址端口bind(sfd)正式开始监听listen()阻塞等待TCP3次握手cfdaccept(sfd)开启新线程处理cfd的读写。
  UDP服务器程序一般是这样的流程:创建服务器描述符sfdsfdsocket()把服务器fd绑定地址端口bind(sfd)直接接受客户端数据包recvfrom()
  可以看到,UDP实际上是TCP的简化版。recvfrom是一个阻塞函数。IP层有数据包到了,就检查IPheader的协议字段,判断IPbody里是不是udp的数据,如果是就激活recvfrom(),这样UDP就能拿到客户端的数据。这个激活,好像是一个软中断还是一个信号,具体在linux4。4内核的哪一块代码,我需要花点时间找一找,先埋个坑,后续补充,暂时理解为激活就行。
  从UDP跟IP层的交互来看,你可以看到,实际上没有什么多路,所有的客户端数据都在一路里面传递给IP层,再由IP层传给UDP层recvfrom()。
  既然如此,那为什么TCP会出现多路,而且因为多路带来性能问题,需要再用epoll解决。
  这里就需要先讲解一下什么是面向连接的协议?
  我们在教科书经常看到,TCP是面向连接的,而UDP不是。
  实际上上面这句话是什么意思呢?
  首先,TCP的实现是在linux内核代码里面的,所以TCP属于linux内核的一部分。
  首先讲解一下,连接状态,它并不是特别真实的一个东西,这个东西比较虚,连接状态,只是内存里面的一个变量,而且还不是实时更新的。
  为什么说它不是实时更新的,就是当底层网络,通信链路不可达的时候,什么是通信链路不可达?直接把中间路由的网线拔开就是了。
  当通信链路不可达的时候,TCP里面的链接状态不会非常快的更改为断开状态。之前在《视频传输协议设计》演示过,把网线拔开之后,TCP要经过多次重传失败,才会认定底层通信链路不可达,然后返回一个信号给调用层。当网线断开的时候,TCP客户端从重试到确认链接断开用了19秒才知道网线断开。
  所以说TCP里面的连接状态只是内存的一个变量,一个虚拟的东西。
  再来说说,为什么协议栈的发展,会演变出连接状态这个内存变量?
  要讲这个问题,就需要先讲为什么广域网的协议,基本上都有3次握手,TCP,UDT,SRT,你可以看到这些协议都有3次握手。
  TCP的3次握手是自带的,UDT是基于UDP的协议,自己实现3次握手,SRT是基于UDT的。
  这个先抛出个问题,UDT既然是用UDP实现的,UDP本身没有3次握手,没有不是更好,可以少几次RTT的时间,通信更快。
  为什么UDT还要自己搞一套3次握手,不用3次握手不是更快吗?
  从直觉来讲,没有3次握手,确实会更快,例如IP层,MAC层的各种协议,就没有什么3次握手。
  但是,需要注意的是,IP层MAC层,他是工作在路由器,交换机里面的,他的数据包发给下一站就完事了,通常下一站不是太远。
  而UDT,TCP,他们的传输,可能是从东大陆到北极,100M的数据,从东大陆某个主机发出来,经过那么多路由器,交换机,跨越海洋,到达北极的某台服务器。如果没有3次握手,提取沟通一下双方的一些情况,100M的传输效率会极其低下,并不会因为没有3次握手而更快,相反,由于上层协议栈没有握手导致一些信息掌握不全面,发送跟接受策略不行,会导致IP层丢包,大量重传。
  所以3次握手,干的是什么的事?就是提前沟通一下双方的信息,例如我的MTU是多少,你的MTU是多少之类的。
  这里再抛出另一个问题,为什么是3次握手,不是4次,2次?
  这个问题实际上是一个ACK设计问题,由于IP层不可靠会丢包,特别是经过那么多路由器转发,丢包的概率会增加,例如路由器负载太高,他就会丢弃数据包减轻负载。
  所以基于IP层的协议,想要在广域网上实现可靠传输,都需要自己实现一套ACK机制,TCP自带ACK,UDT协议是自己实现ACK。
  因为ACK机制的出现,再加上广域网上传输可靠数据需要提前沟通,沟通好才开始正式开始传输数据。
  ACK提前沟通,就形成了3次握手,举个例子。
  客户端要开始传数据给服务器,客户端先发一个UDP包,里面有他的MTU等信息,然后服务器端收到了这个UDP包,因为要有确认机制,所以服务器需要发一个ACK的UDP包给客户端,告诉客户端,服务器已经收到了他MTUUDP包。但是同时,服务器也需要告诉客户端自己的一些信息,为了提高效率,服务器的MTU信息也会放进去ACK里面一起返回去给客户端。
  然后客户端收到了服务器的ACK,客户端知道MTU信息服务器端拿到了,客户端就不会重传。同时,客户端也收到服务器的MTUUDP包,客户端需要回复服务器一个ACK,说自己拿到了。
  上面这些流程,就是3次握手,也就是TCP里面的SYNACKSYNACK。
  回到之前的问题,为什么UDP不需要多路复用,是因为UDP他本身没实现3次握手跟链接状态的功能。那是不是如果一个基于UDP的协议栈实现了3次握手跟建立连接,就会需要多路复用,其实也不是。
  C音视频开发学习资料:点击领取1音视频开发(资料文档视频教程面试题)(FFmpegWebRTCRTMPRTSPHLSRTP)
  举个例子,基于UDP设计一个协议。我把他叫UDL。
  简洁的流程如下:
  1,服务器recvfrom()阻塞等待IP层把IPbody的数据丢上来。
  2,服务器recvfrom()拿到了客户端的UDP数据,有端口,有客户端IP,有客户端MTU这些数据。
  3,服务器开始回复ACK,3次握手省略,3次握手成功之后然后我服务器创建一个map,把客户端IPPORT作为一个key传进去map,代表这个客户端IPPORT已经建立连接了。可以正式传输数据。
  4,服务器继续阻塞在recvfrom()等待数据。
  5,服务器再次从recvfrom()拿到UDP包,检测UDP包里面有没有SYN,如果有就是开一个新的链接,没有SYN就在map里面找客户端IPPORT,如果存在就继续走,如果不存在就代表之前没建立连接,没沟通好,不能传数据,直接把RST标记放进去UDP发回去。
  6,这里服务器每次从recvfrom()拿到UDP包,都是丢给线程池处理,主线程不阻塞处理。
  上面的流程,我基于UDP实现了一个3次握手,跟链接状态,大家觉得里面有没用到多路复用?我觉得没有,由此至终都是有一个路,所有客户端数据都是通过
  recvfrom()拿到了,然后传给线程池处理。
  那为什么TCP有多路复用跟EPOLL,是因为TCP把3次握手,链接状态等等东西,封装进内部逻辑,做了抽象,方便调用层使用。
  上层协议栈,实现了3次握手跟链接状态的功能并不会出现多路复用,而是由于对这些东西做了封装才会出现多路复用,这个具体是什么意思呢?
  我再仔细讲解一下,Linux里面有个谚语一切皆文件,包括TCP的socket也是一个文件描述符,tcp的socketfd是跟文件fd,复用了一个内核的数据结构,由于linux内核打开的文件描述符是有限制了,这个封装通用设计,就会导致一些问题。
  大家可以看看上面的UDL协议设计,并没打开什么文件描述符,我只是申请了块内存,来存客户端IPPORT的链接状态。
  因为TCP的内部实现用了文件描述符这个数据结构,所以他受到了文件描述符的数量限制。这是TCP实现没考虑的问题。TCP实现是linux内核实现的一部分。
  TCP里面的客户端socketfd,实际上跟上面的UDL一样,只是把客户端IPPORT转成一个socketfd,一个整数,方便调用层使用。
  讲了这么多,还没开始讲,TCP为什么就有多路,而且要复用,而我们上面自己基于UDP实现的类似协议,却没有多路,也不需要复用。
  其实这个问题我自己也不是很清楚,估计是因为TCP里面的网络fd跟操作系统的文件fd是共用的某个数据结构,所以一个TCP网络fd,跟文件fd是一样的,写一个文件就是一路,写多个文件就是多路。系统的文件描述符可以监听变化,TCP服务器会生成很多的clientfd,每个线程阻塞监听clientfd效率太低,所以出了epoll统一监听所有网络fd。
  所以说,估计是因为TCP的内部实现跟操作系统的文件实现耦合太严重了,导致他出现多路,需要epoll来解决。
  TCP应用早期有C10k问题,但是运营商的NAT硬件防火墙,要处理的TCP链接,肯定超过10k,他是怎么解决的?修改linux内核,或者不用linux内核,把硬件性能压榨到极致。TCP标准只是定义了TCP的行为,没有强制一定要像linux内核那样跟文件系统通用数据结构。可以自行实现TCP的行为,符合标准就行。
投诉 评论 转载

UDP为什么没有epoll首先,讲讲UDP编程为什么不需要用到系统的epoll函数,RichardStevens在不朽的经典《Unix网络编程卷一》中已经说了:大多数情况下,TCP服务器是并发的,……小米12换成redmiK50,出自同一家的兄弟,真实体验不吐小米这两年一直在冲击高端,两年前的小米10系列,让我们看到了一些希望,小米11系列其实蛮不错,尤其是小米11Ultra,更是让人眼前一亮,只不过高通骁龙888处理器你太过拉垮,……向英雄司机杨勇同志致敬2022年6月四日,贵阳北至广州南的D2809次动车因撞上泥石流导致脱轨,致司机不幸殉职,另有八名乘客不同程度受伤。事故现场事故发生后,中国铁路发布消息称:经车载数……书画为媒话环保安徽省环保联合会举办六五环境日主题纪念活动6月5日是世界环境日,今年环境日主题为共建清洁美丽世界。为深入贯彻落实习近平生态文明思想,纪念第51个六五世界环境日暨第12个安徽环保宣传周,6月5日上午,安徽省环保联合会组织……中篇小说迷乱的色欲(三)不知过了多长时间,纳莎苏醒了过来。她努力回忆刚才发生的一切,并四下寻找顾娇娇的身影,目及所至没有发现她,一阵剧痛让纳莎又昏了过去。山区的气候多变,刚才还是万里无云的晴朗天……人性之恶,我为爱人讨公道(一)这是贝儿自订婚后第一次再次跨进未婚夫浩然位于深山的这个豪华的古宅。所谓古宅,总会是阴森悚然了点。贝儿每次探访这里,总觉得毛骨悚然。她在城市中长大,虽然对古建筑……70年代年代女巨贪包养七名情夫,生活奢淫无度,最终被情夫举报1977年7月24日,江苏如东县,酷暑刚过。如东中学的操场上酷热难耐,但本该在树荫下乘凉的人们却聚集在这里。今天,将在这个操场上举行公开审判会议,宣布对一名囚犯的判决。……中国失去欧洲了吗今年6月29日一30日,在西班牙首都马德里举行的北约峰会上,北约推出了《新战略》概念,首次将中国定义为系统性挑战。这是介于伙伴与威胁之间的中间地带,意味着北约即将在今后的十年时……海南橡胶(601118。SH)签订海南橡胶2022年橡胶收入智通财经APP讯,海南橡胶(601118。SH)公告,近日,公司与中国人民财产保险股份有限公司海南省分公司、中国太平洋财产保险股份有限公司海南分公司签订了《海南橡胶2022年橡……尺寸轴距均提升!换思域同款内饰本田CR作为紧凑型SUV领域中的常青树车型,本田CRV凭借着宽敞的乘坐空间、良好的机械素质、出色的燃油经济性以及本田金漆招牌加持下,迅速成为在世界上最受消费者欢迎的车型之一。而这……就算一眼万年,也,得适合我从第一眼看到水仙花的时候,就很喜欢,但可惜,我一碰到这花就会过敏我想说的是,其实很多人,即使一见钟情,一眼万年,也没用,得合适!平底鞋给不了高跟鞋的骄傲,高跟鞋也给不了……李鸿章是如何用卑鄙手段扳倒红顶商人胡雪岩的?在历史上,左宗棠和李鸿章的矛盾是天下皆知,两个人意见不同,一个主张战斗求战派,一个主张讲和和解派。在左宗棠收复了新疆之后,他的声望跟地位是达到了顶峰,李鸿章就眼红。他就发……
皇帝也难当大明历史上在位最短,也最命苦的皇帝从社会层面入手,浅析唐朝人员垂直流动的影响陕西黑猫产能狂飙再增资27亿扩产碳中和背景下环保问题待解敦煌出土墓碑,揭开玄武门之变真相,学者难怪李建成被轻易杀死隋文帝时期大兴洛阳之间的梯级漕运体系,地位和作用是什么?Netty百万连接场景下性能调优教程我国工业经济运行正回升向好恐高症的他首次高空作业,救下悬空幼童被称蜘蛛侠文艺赋能冲刺亚运我们的亚运我们的盛会我们的村晚上演数说湖南妇儿十四五市州谈丨长沙砥砺前行,改革创新,推动妇女儿优衣库柳井正日本工资水平低,或再加薪年过花甲坚持手工制作灯笼,承传古老的文化韵味

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找