[原]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 ...
随机推荐
- requests的content与text导致lxml的解析问题
title: requests的content与text导致lxml的解析问题 date: 2015-04-29 22:49:31 categories: 经验 tags: [Python,lxml, ...
- Modify Branding of FreeCAD
Modify Branding of FreeCAD eryar@163.com This article describes the Branding of FreeCAD. Branding me ...
- Minor【 PHP框架】1.简介
1.1 Minor是什么 Minor是一个简单但是优秀的符合PSR4的PHP框架,It just did what a framework should do. 只做一个框架应该做的,简单而又强大! ...
- Coroutine in Java - Quasar Fiber实现--转载
转自 https://segmentfault.com/a/1190000006079389?from=groupmessage&isappinstalled=0 简介 说到协程(Corout ...
- 终端mysql Operation not permitted错误解决方案
前言 前段时间装mysql,就遇到了ln: /usr/bin/mysql: Operation not permitted的错误,网上好多方法都过时了,下边是我的解决方法 原因 这是因为苹果在OS X ...
- 获取 dhcp IP 过程分析 - 每天5分钟玩转 OpenStack(91)
前面我们已经讨论了 DHCP agent 的配置以及 namespace 如何隔离 dnsmasq 服务,本节将以 cirros-vm1 为例分析获取 DHCP IP 的详细过程. 在创建 insta ...
- javascript 笔记!
1.通过javascript向文档中输出文本 document是javascript的内置对象,代表浏览器的文档部分 document.write("Hello Javascript&quo ...
- Android之DOM解析XML
一.DOM解析方法介绍 DOM是基于树形结构的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树,检索所需数据.分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息 ...
- MySQL,MariaDB:Undo | Redo [转]
本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版 ...
- Collections
2017-01-06 22:50:43 数据结构和算法 <如何学习数据结构?>:https://www.zhihu.com/question/21318658 <How do I ...