5-09 ET、LT深释,服务器设计、粘包解决

一:ET,LT模式深入分析及测试

LT:水平触发/低速模式,这个事件没处理完,就会被 一直触发;
ET:边缘触发/告诉模式,这个事件通知只会出现一次;
普遍认为ET比LT效率高一些,但是 ET编程难度比LT大一些;
ET模式下,如果没有数据可接收,则recv会返回-1

思考:为什么ET模式事件只触发一次[事件被扔到双向链表中一次,被epoll_wait取出后就干掉]
   LT模式事件会触发多次呢?[事件如果没有处理完,那么事件会被多次往双向链表中扔]

如何选择ET,还是LT
如果收发数据包有固定格式【后续会讲】,那么老师建议采取LT:编程简单,清晰,写好了效率不见得低;
老师准备本项目中采用LT这种方法【固定格式的数据收发方式来写我们的项目】

如果收发数据包没有固定格式,可以考虑采用ET模式;

二:我们的服务器设计

(2.1)服务器设计原则总述

我们写的是:通用的服务框架:将来,稍加改造甚至不用改造就可以把它直接应用在很多的具体开发工作中;
 我们的工作重点就可以聚焦在业务逻辑上; 相当于你自带框架【自带源码】入职;甚至你可以挑战高级程序员/主程序这种职业;

(2.2)收发包格式问题提出

第一条命令出拳【1abc2】,第二条加血【1def2|30】; 
1abc21def2|30

(2.3)TCP粘包、缺包

tcp粘包问题
client发送abc,def,hij,三个数据包发出去;

(a)客户端粘包现象 客户端因为有一个Nagle优化算法; send(“abc”); write()也可以 send(“def”);
send(“hij”); 因为Nagle算法存在的,这三个数据包被Nagle优化算法直接合并一个数据包发送出去;这就属于客户端粘包;
如果你关闭Nagle优化算法,那么你调用几次send()就发送出去几个包;那客户端的粘包问题就解决了;

b)服务器端粘包现象 不管你客户端是否粘包,服务器端都存在粘包的问题:就算你客户端不粘包,但是,仍然避免不了服务器端粘包的问题;
服务器端两次 recv之间可能间隔100毫秒,那可能在这100毫秒内,客户端这三个包都到了,这三个包都被保存到了服务器端的
针对该TCP连接收数据缓冲中【abcdefhij】;你再次recv一次,就可能拿到了全部的“abcdefhij”,这就叫服务器端的 粘包; 再举一例: send(“abc…”); //8000字节;这个可能被操作系统拆成6个包发送出去了;
网络可能出现延迟或者阻塞, 服务器端第一次recv() = “ab” recv = “c…”, recv…
recv() = “…de”… [缺包]

(2.4)TCP粘包、缺包解决:面试服务器岗位经常考,没听说过粘包或者不会解决TCP粘包这个问题,那么会立即被pass;

粘包,要解决的就是吧这几个包拆出来,一个是一个; 解决粘包的方案很多;老师提供的方案是简单、严谨、有效的一种解决方案; 严谨
,很多服务器程序员不考虑 恶意数据包; 服务器程序员不能假设收到的数据包都是善意 的,合理的,构造畸形数据包

如何解决拆包问题:给收发的数据包定义一个统一的格式[规则];c/s都按照这个格式来,就能够解决粘包问题;
包格式: 包头+包体 的格式;其中 包头 是固定长度【10字节】,在包头中,有一个成员变量会记录整个包【包头+包体】的长度;
这样的话,先收包头,从包头中,我知道了整个包的长度,然后 用整个包的长度 - 10个字节 = 包体的长度。
我再收 “包体的长度”这么多的字节; 收满了包体的长度字节数,我就认为,一个完整的数据包【包头+包体】收完;

收包总结:

(1)先收固定长度包头 10字节; (2)收满后,根据包头中的内容,计算出包体的长度:整个长度-10
(3)我再收包体长度这么多的数据,收完了,一个包就完整了; 我们就认为受到了一个完整的数据包;从而解决了粘包的问题;

总结

官方的nginx的代码主要是用来处理web服务器【一种专用的服务器】,代码写的很庞杂;
不太适合咱们这种固定数据格式【包头+包体】的服务器【通用性强的服务器,可以应用于各种领域】。
所以,后续服务器代码,老师带着大家以老师自由发挥为主,共同领略服务器开发的各种风景,精彩继续;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这是一门linuxc++通讯架构实战课程,针对c/c++语言已经掌握的很熟并希望进一步深造以将来用c++linux下从事网络通讯领域/网络服务器的开发和架构工作。这门课程学习难度颇高但也有着极其优渥的薪水(最少30K月薪,最高可达60-80K月薪),这门课程,会先从nginx源码的分析和讲解开始,逐步开始书写属于自己的高性能服务器框架代码,完善个人代码库,这些,将会是您日后能取得高薪的重要筹码。本课程原计划带着大家逐行写代码,但因为代码实在过于复杂和精细,带着写代码可能会造成每节课至少要4~5小时的超长时间,所以老师会在课前先写好代码,主要的时间花费在逐行讲解这些代码上,这一点望同学们周知。如果你觉得非要老师领着写代码才行的话,老师会觉得你当前可能学习本门课程会比较吃力,请不要购买本课程,以免听不懂课程并给老师差评,差评也会非常影响老师课程的销售并造成其他同学的误解。 这门课程要求您具备下面的技能:(1)对c/c++语言掌握的非常熟练,语言本身已经不是继续学习的障碍,并不要求您一定熟悉网络或者linux;(2)对网络通讯架构领域有兴趣、勇于挑战这个高难度的开发领域并期望用大量的付出换取高薪;在这门课程中,实现了一个完整的项目,其中包括通讯框架和业务逻辑框架,浓缩总结起来包括如下几点:(1)项目本身是一个极完整的多线程高并发的服务器程序;(2)按照包头包体格式正确的接收客户端发送过来的数据包, 完美解决收包时的数据粘包问题;(3)根据收到的包的不同来执行不同的业务处理逻辑;(4)把业务处理产生的结果数据包正确返回给客户端;本项目用到的主要开发技术和特色包括:(1)epoll高并发通讯技术,用到的触发模式是epoll中的水平触发模式【LT】;(2)自己写了一套线程池来处理业务逻辑,调用适当的业务逻辑处理函数处理业务并返回给客户端处理结果;(3)线程之间的同步技术包括互斥量,信号量等等;(4)连接池中连接的延迟回收技术,这是整个项目中的精华技术,极大程度上消除诸多导致服务器程序工作不稳定的因素;(5)专门处理数据发送的一整套数据发送逻辑以及对应的发送线程;(6)其他次要技术,包括信号、日志打印、fork()子进程、守护进程等等;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值