从零构建通讯器--5.8 ET、LT深入分析及测试,服务器设计、粘包解决
发布日期:2021-05-04 18:23:34 浏览次数:15 分类:技术文章

本文共 1635 字,大约阅读时间需要 5 分钟。

(1)ET,LT模式深入分析及测试

1)ET:边缘触发/告诉模式,这个事件通知只会出现一次;
普遍认为ET比LT效率高一些,但是 ET编程难度比LT大一些,ET模式下,如果没有数据可接收,则recv会返回-1;egain表示再触发一次再为-1时,就触发break,防止第一次出现-1只是一个提示时就不需要退出
在这里插入图片描述
若客户端断开
在这里插入图片描述
服务器端设置成若n=0,break
在这里插入图片描述
2)LT:水平触发/低速模式,这个事件没处理完,就会被 一直触发;
设置成LT模式,epollet设置成0
在这里插入图片描述
LT测试代码
在这里插入图片描述

LT效果

在这里插入图片描述
LT简单多了
②思考:
1)为什么ET模式事件只触发一次[事件被扔到双向链表中一次,被epoll_wait取出后就干掉]
2)LT模式事件会触发多次呢?[事件如果没有处理完,那么事件会被多次往双向链表中扔]
③如何选择ET,还是LT
1)//如果收发数据包有固定格式【后续会讲】,那么老师建议采取LT:编程简单,清晰,写好了效率不见得低;
//老师准备本项目中采用LT这种方法【固定格式的数据收发方式来写我们的项目】
2)如果收发数据包没有固定格式,可以考虑采用ET模式(官方采用ET模式);

(2)我们的服务器设计

(2.1)服务器设计原则总述
我们写的是:通用的服务框架:将来,稍加改造甚至不用改造就可以把它直接应用在很多的具体开发工作中;
我们的工作重点就可以聚焦在业务逻辑上; 相当于你自带框架【自带源码】入职;甚至你可以挑战高级程序员/主程序这种职业;
(2.2)收发包格式问题提出
第一条命令出拳【1abc2】,第二条加血【1def2|30】;
命令:1abc21def2|30
(2.3)TCP粘包、缺包
①tcp粘包问题
client发送abc,def,hij,三个数据包发出去;
②a)客户端粘包现象(没必要解决客户端粘包问题)
客户端因为有一个Nagle优化算法;(100到200毫秒内)
//send(“abc”); write()也可以
//send(“def”);
//send(“hij”);
因为Nagle算法存在的,这三个数据包被Nagle优化算法直接合并一个数据包发送出去;这就属于客户端粘包;
如果你关闭Nagle优化算法,那么你调用几次send()就发送出去几个包;那客户端的粘包问题就解决了;
③b)服务器端粘包现象
不管你客户端是否粘包,服务器端都存在粘包的问题:就算你客户端不粘包,但是,仍然避免不了服务器端粘包的问题,针对该TCP连接收数据缓冲中【abcdefhij】;你再次recv一次,就可能拿到了全部的“abcdefhij”,这就叫服务器端的 粘包;
(2.4)TCP粘包、缺包解决:面试服务器岗位经常考,没听说过粘包或者不会解决TCP粘包这个问题,那么会立即被pass;
1)方法:如何解决拆包问题:给收发的数据包定义一个统一的格式[规则];c/s都按照这个格式来,就能够解决粘包问题;
2)具体:
①包格式: 包头+包体 的格式;其中 包头 是固定长度【10字节】,在包头中,有一个成员变量会记录整个包【包头+包体】的长度;
②这样的话,先收包头,从包头中,我知道了整个包的长度,然后 用整个包的长度 - 10个字节 = 包体的长度。
③我再收 “包体的长度”这么多的字节; 收满了包体的长度字节数,我就认为,一个完整的数据包【包头+包体】收完;
3)收包总结:
//(1)先收固定长度包头 10字节;
//(2)收满后,根据包头中的内容,计算出包体的长度:整个长度-10
//(3)我再收包体长度这么多的数据,收完了,一个包就完整了;
//我们就认为受到了一个完整的数据包;从而解决了粘包的问题;
在这里插入图片描述

补充:

官方的nginx的代码主要是用来处理web服务器【一种专用的服务器】,代码写的很庞杂;
不太适合咱们这种固定数据格式【包头+包体】的服务器【通用性强的服务器,可以应用于各种领域】

web服务器接受各种格式的数据

上一篇:windows 右键菜单中添加在vscode 打开
下一篇:从零构建通讯器--5.6 通讯代码精粹之epoll函数实战1(连接池)

发表评论

最新留言

不错!
[***.144.177.141]2025年04月06日 08时51分44秒