[原]Cachedb 网络模块文档
Cachedb 网络模块文档
整体结构
- 多路复用 (epoll 模块)
- 事件驱动 (事件封装)
- 缓冲管理 (上层buffer管理)
设计思想
层次化的设计,每一个模块只调用上一个模块的接口,并将耦合聚拢于接口处,同时每个模块也只暴露固定的操作接口给上层调用。
如果下层需要依赖上层的一些操作,将这部分操作提取出接口,由上层调用的时候将接口实现传递给下层。
最终整个网络模块只暴露了对于缓冲区的几个操作,不需要考虑数据收发时候的套接字状态等。
详细介绍
1. 多路复用
struct eventOps {
char *name;
int32_t (*init)(void);
int32_t (*add)(struct event *);
int32_t (*mod)(struct event *);
int32_t (*del)(struct event *);
int32_t (*run)(struct epollOpe *, int32_t timeout);
};
struct eventOps epoll = {
"GNU/Linux/EPOLL",
&epoll_init,
&epoll_add,
&epoll_mod,
&epoll_del,
&epoll_run
};
通过此结构(interface),将epoll操作与系统实际的模块隔离,底层可以使用SELECT或者KQUEUE
其他模块通过以下方式导入IO多路复用模块,将耦合点聚拢在接口处。接口供上层event调用
extern struct eventOps epoll ;
2. 事件驱动
事件驱动主要围绕Reactor来设计,其中Reactor维护三个队列
- ININITQUEUE 初始化队列,事件最初状态
- ININITQUEUE 信号队列,其中保存了被触发后的事件
- INCLOSEQUEUE 关闭队列,处于此队列中的事件将被移除反应堆并关闭连接,调用close callback回收资源
- INERRORQUEUE 错误队列,处于此队列中的事件将调用error callback函数
Reactor是一个全局的结构,是所有event的归属。
事件驱动模块提供了以下几个接口供buffer层调用
int32_t eventSelfInit(struct event *_ev, \
int32_t fd, \
int32_t mode, \
evCallback *_evCb, \
evErrorCb *_errCb, \
void *_errArgs);
/*
Self initilize
Before an event add to reactor, we should init
event with listen fd and set callback of when
event has been occured.
*/
int32_t eventAddListen(struct reactor *_R, struct event *_ev);
/*
Add an event to reactor
*/
int32_t eventRmListen(struct reactor *_R, struct event *_ev);
/*
Remove from reactor
*/
int32_t eventModListen(struct event *_ev, int fd, int32_t mode, evCallback *_evCb);
/*
Modify listen mode
*/
void setEventError(struct event *_ev);
/*
Set event error when error raise, when event has been set error flag
error callback will be called
*/
void setEventClose(struct event *_ev);
/*
Set error close when server close or been closed
when event has been set close flag,
close callback will be called, close callback may
as same as error callback.
*/
struct reactor * reactorInit(int32_t maxConNum);
/*
init reactor with max connection number
*/
void destroyReactor(struct reactor * _R);
/*
Destroy a reactor
*/
3.缓冲管理
通过层次化的设计,将上述三个模块隔离开,最终在buffer层导出以下几个接口
struct buffer * createBuffer(struct reactor * _R, int32_t socket);
/*
create a buffer object, with a socket you which you want to
set to reactor.
*/
int32_t bufferWrite(struct buffer * _B, char *buf, int32_t n);
/*
NOTICE: In bufferWrite, datas would be send to socket directly.
when net device not ready, send will return a value of
EAGAIN or EINTR.
In this case, we should copy data to write buffer of our self,
and add write event to reactor, write event will trigger
when net device ready.
*/
int32_t bufferReadUntil(struct buffer * _B, int32_t n, readCb *rcb, void *args);
/*
Set callback to buffer when then buffer size >= n.
when read_buffer >= n, the read callback will be trigger.
NOTICE, the read callback should return the actual number of used.
*/
void bufferReadContinue(struct buffer * _B, int nNeed);
/*
when you read from socket with number of n, but there are not a whole
package you want, you should set the number of n you want the next event
trigger.
*/
int32_t bufferReadSplit(struct buffer * _B, char * split, int32_t nSplit, readCb *rcb, void *arg);
/*
Set callback to buffer when there are split char in buffer.
ex:
GET / HTTP/1.1\r\n\r\n
Host: www.baidu.com\r\n\r\n
the \r\n\r\n is char split.
*/
void disBuffer(struct buffer * _B);
使用场景:每次有连接请求到来的时候,Accept连接后创建一个buffer结构,用于管理此连接的数据收发操作。
其中buffer提供了write 和 两种读的方式
- bufferWrite 直接将数据写入到缓冲区,缓冲区会写到socket,如果socket写满,将此socket注册到 epoll中,事件类型为 WRITEN
- bufferReadUntil, 当缓冲区中的数据满足参数n的时候,调用注册到缓冲区的callback,此callback一般为协议处理函数,其中返回的个数为实际使用到的buffer中的字节数M,底层buffer管理会将此buffer向前挪动M个字节
- bufferReadContinue, 当读取完数据后,如果还需要继续读取N个字节的数据,调用此函数
- bufferReadSplit,和bufferReadUntil类似,触发条件为buffer 中存在split的分隔符时候,一般用于字符流的处理
[原]Cachedb 网络模块文档的更多相关文章
- 解决Spring的java项目打包后执行出现“无法读取方案文档...“、“原因为 1) 无法找到文档; 2) 无法读取文档; 3) 文档的根元素不是...”问题
问题 一个用Spring建的java项目,在Eclipse或idea中运行正常,为什么打包后运行出现如下错误呢? 2019/07/10/19:04:07 WARN [main] org.springf ...
- 【原】Spring Boot 配置swagger2没有文档解决方案
@Bean public Docket customImplementation(){ return new Docket(DocumentationType.SWAGGER_2) .select() ...
- 【原】中文Ubuntu主目录下的文档文件夹改回英文
想把中文Ubuntu主目录下的文档文件夹改回英文,在Terminal下面操作的时候要输入中文特别不方便,于是便用了更改名字的想法 方法一: 首先把那几个中文名称修改成相应的英文,比如 Desktop. ...
- Windows7下使用sphinx生成开源文档(原)
作者这里以osgearth文档为例,感觉这种生成文档的方式比较好,生成的html文档是支持搜索的,感谢开源工作者的奉献.赞一个 1. 下载并安装python for windows:https://w ...
- 【开源】.Net Api开放接口文档网站
开源地址:http://git.oschina.net/chejiangyi/ApiView 开源QQ群: .net 开源基础服务 238543768 ApiView .net api的接口文档查看 ...
- VS2010 release编译下进行调试,“当前不会命中任何断点,还没有为文档加载”问题解决方案
在release模式下调试程序,经常出现"当前不会命中任何断点,还没有为文档加载"的问题,可尝试以下方法: 1. 属性 → 配置属性 → C/C++ → 常规 → 调试信息格式:选 ...
- 详解微信开发者文档——5 access_token管理
写在前面的话:前几篇博客详细讲解了如何获取用户发送的消息并进行回复,这里的回复是一种被动的回复,而被动回复的方式便是通过echo返回信息给微信服务器的POST请求,因此,其实我们并没有算的上调用了微信 ...
- SpingMVC 核心技术帮助文档
声明:本篇文档主要是用于参考帮助文档,没有实例,但几乎包含了SpringMVC 4.2版本的所有核心技术,当前最新版本是4.3,4.2的版本已经经是很新的了,所以非常值得大家一读,对于读完这篇文档感觉 ...
- Kotlin开发语言文档(官方文档)-- 目录
开始阅读Kotlin官方文档.先上文档目录.有些内容还未阅读,有些目录标目翻译还需琢磨琢磨.后续再将具体内容的链接逐步加上. 文档链接:https://kotlinlang.org/docs/kotl ...
随机推荐
- 你必须知道的EF知识和经验
注意:以下内容如果没有特别申明,默认使用的EF6.0版本,code first模式. 推荐MiniProfiler插件 工欲善其事,必先利其器. 我们使用EF和在很大程度提高了开发速度,不过随之带来的 ...
- HTML5 sessionStorage会话存储
sessionStorage 是HTML5新增的一个会话存储对象,用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据.本篇主要介绍 sessionStorage(会话存储) ...
- Minor【 PHP框架】1.简介
1.1 Minor是什么 Minor是一个简单但是优秀的符合PSR4的PHP框架,It just did what a framework should do. 只做一个框架应该做的,简单而又强大! ...
- submit text3常用快捷键
在网上找了一些submit text的快捷键: Ctrl+D 选词 (反复按快捷键,即可继续向下同时选中下一个相同的文本进行同时编辑)Ctrl+G 跳转到相应的行Ctrl+J 合并行(已选择需要合并的 ...
- jquery.cookie的使用
今天想到了要为自己的影像日记增加赞的功能,并且需要用到cookie. 记得原生的js操作cookie也不是很麻烦的,但似乎jquery更简单,不过相比原生js,需要额外引入2个文件,似乎又不是很好,但 ...
- (转)从0开始搭建SQL Server AlwaysOn 第二篇(配置故障转移集群)
原文地址: http://www.cnblogs.com/lyhabc/p/4682028.html 这一篇是从0开始搭建SQL Server AlwaysOn 的第二篇,主要讲述如何搭建故障转移集 ...
- mysql删除重复记录语句的方法
例如: id name value 1 a pp 2 a pp 3 b iii 4 b pp 5 b pp 6 c pp 7 c pp 8 c iii id是主键 要求得到这样的结果 id name ...
- Jquery 获得当前标签的名称和标签属性
得到标签的名称 $("#name").prop("tagName"); 或者 $("#name")[0].tagName; 注意:1.得到的 ...
- 谈谈document.ready和window.onload的区别
在Jquery里面,我们可以看到两种写法:$(function(){}) 和$(document).ready(function(){}) 这两个方法的效果都是一样的,都是在dom文档树加载完之后执行 ...
- 绿色版的Linux.NET——“Jws.Mono”
Linux.NET环境的搭建,不仅是一项比较耗时的事情,同时也是一项略显复杂繁琐的事情.特别是对于近期的几个Mono版本,由于官方所提供的源码包中出现代码文件的缺失,这总让我们的付出变得徒劳.另外一方 ...