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 网络模块文档的更多相关文章

  1. 解决Spring的java项目打包后执行出现“无法读取方案文档...“、“原因为 1) 无法找到文档; 2) 无法读取文档; 3) 文档的根元素不是...”问题

    问题 一个用Spring建的java项目,在Eclipse或idea中运行正常,为什么打包后运行出现如下错误呢? 2019/07/10/19:04:07 WARN [main] org.springf ...

  2. 【原】Spring Boot 配置swagger2没有文档解决方案

    @Bean public Docket customImplementation(){ return new Docket(DocumentationType.SWAGGER_2) .select() ...

  3. 【原】中文Ubuntu主目录下的文档文件夹改回英文

    想把中文Ubuntu主目录下的文档文件夹改回英文,在Terminal下面操作的时候要输入中文特别不方便,于是便用了更改名字的想法 方法一: 首先把那几个中文名称修改成相应的英文,比如 Desktop. ...

  4. Windows7下使用sphinx生成开源文档(原)

    作者这里以osgearth文档为例,感觉这种生成文档的方式比较好,生成的html文档是支持搜索的,感谢开源工作者的奉献.赞一个 1. 下载并安装python for windows:https://w ...

  5. 【开源】.Net Api开放接口文档网站

    开源地址:http://git.oschina.net/chejiangyi/ApiView 开源QQ群: .net 开源基础服务  238543768 ApiView .net api的接口文档查看 ...

  6. VS2010 release编译下进行调试,“当前不会命中任何断点,还没有为文档加载”问题解决方案

    在release模式下调试程序,经常出现"当前不会命中任何断点,还没有为文档加载"的问题,可尝试以下方法: 1. 属性 → 配置属性 → C/C++ → 常规 → 调试信息格式:选 ...

  7. 详解微信开发者文档——5 access_token管理

    写在前面的话:前几篇博客详细讲解了如何获取用户发送的消息并进行回复,这里的回复是一种被动的回复,而被动回复的方式便是通过echo返回信息给微信服务器的POST请求,因此,其实我们并没有算的上调用了微信 ...

  8. SpingMVC 核心技术帮助文档

    声明:本篇文档主要是用于参考帮助文档,没有实例,但几乎包含了SpringMVC 4.2版本的所有核心技术,当前最新版本是4.3,4.2的版本已经经是很新的了,所以非常值得大家一读,对于读完这篇文档感觉 ...

  9. Kotlin开发语言文档(官方文档)-- 目录

    开始阅读Kotlin官方文档.先上文档目录.有些内容还未阅读,有些目录标目翻译还需琢磨琢磨.后续再将具体内容的链接逐步加上. 文档链接:https://kotlinlang.org/docs/kotl ...

随机推荐

  1. TODO:Laravel 使用blade标签布局页面

    TODO:Laravel 使用blade标签布局页面 本文主要介绍Laravel的标签使用,统一布局页面.主要用到到标签有@yield,@ stack,@extends,@section,@stop, ...

  2. 免费开源的DotNet任务调度组件Quartz.NET(.NET组件介绍之五)

    很多的软件项目中都会使用到定时任务.定时轮询数据库同步,定时邮件通知等功能..NET Framework具有“内置”定时器功能,通过System.Timers.Timer类.在使用Timer类需要面对 ...

  3. 通过AngularJS实现前端与后台的数据对接(一)——预备工作篇

    最近,笔者在做一个项目:使用AngularJS,从而实现前端与后台的数据对接.笔者这是第一次做前端与后台的数据对接的工作,因此遇到了许多问题.笔者在这些问题中,总结了一些如何实现前端与后台的数据对接的 ...

  4. VS2015常用快捷键总结

    生成解决方案 F6,生成项目Shift+F6 调试执行F5,终止调试执行Shift+F5 执行调试Ctrl+F5 查找下一个F3,查找上一个Shift+F3 附加到进程Ctrl+Alt+P,逐过程F1 ...

  5. Java中用得比较顺手的事件监听

    第一次听说监听是三年前,做一个webGIS的项目,当时对Listener的印象就是个"监视器",监视着界面的一举一动,一有动静就触发对应的响应. 一.概述 通过对界面的某一或某些操 ...

  6. C#事件-使用事件需要的步骤

    事件是C#中另一高级概念,使用方法和委托相关.奥运会参加百米的田径运动员听到枪声,比赛立即进行.其中枪声是事件,而运动员比赛就是这个事件发生后的动作.不参加该项比赛的人对枪声没有反应. 从程序员的角度 ...

  7. 转:MSSQL还原单mdf文件报1813错误

    原文地址:http://www.cnblogs.com/clownkings/p/4950865.html 解决办法: 1.首先要备份好mdf文件,如果他没了经理非吃了你不可.都不吐骨头的. 2.在数 ...

  8. hibernate5.2需要的最少jar文件

    hibernate5.2需要的最少jar文件: required文件夹中的所有jar文件 + mysql-connector-java-bin.jar.

  9. 我的MYSQL学习心得(十一) 视图

    我的MYSQL学习心得(十一) 视图 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  10. 分享在Linux下使用OSGi.NET插件框架快速实现一个分布式服务集群的方法

    在这篇文章我分享了如何使用分层与模块化的方法来设计一个分布式服务集群.这个分布式服务集群是基于DynamicProxy.WCF和OSGi.NET插件框架实现的.我将从设计思路.目标和实现三方面来描述. ...