使用C++实现简单的Reactor模式
注:本文是阅读 muduo 网络库之后的理解以及自己的代码实现
IO 多路复用是 Reactor 的核心,简单来说,我们将多个文件描述符存放于一个统一的框架之中进行管理,每当某一个文件描述符中发生了某个事件,系统就去执行对应的响应函数,这也被称为回调。如图 1 所示是 Reactor 的流程描述,fd_2变为红色代表着该文件描述符当前存在激活事件,系统将其推入Event Callback Trigger的卡槽中,代表着fd_2的开关开启,系统开始执行对应的回调函数。
实现一个 Reactor 模式需要将其中的几个核心部件进行拆分。
首先,我们知道,对于对象,它们都拥有自己的回调函数,而对象本身,在 Linux 中可以用文件描述符进行表示,这包括但不限于各类文件资源、标准输入输出、SOCKET 通信甚至是定时器。综上,对于这一块,我们使用一个class Channel对一个文件描述符和它对应的回调函数进行封装,这在图 1 中对应了各个橙色的小卡片。
其次,整个系统应该有一个最上层的抽象描述。所谓抽象描述,是我们不去关心具体的实现,而是需要描述出这整个系统的核心特点。在这里,虽然是 IO ...
Acceptor——封装socket系统调用并集成到Reactor框架中
注:本文为阅读了 muduo 网络库源码及作者著作之后对于网络库的复现和笔记
功能我们定义一个class Acceptor,其功能是:让服务器在指定的端口处进行监听,如果在端口监听到连接,则执行由class Acceptor的类用户注册的回调函数。
底层 API首先梳理一下与 Acceptor 相关的底层 API 调用。
int socket(int domain, int type, int protocol)用于创建本地 socket fd,domain指示网络的通信所在域,通常选择AF_INET即可,代表 IPV4;type指示 socket fd 类型,对于 TCP 协议,因为是流式协议,加上我们的网络库的非阻塞特性,而通常还需指定 CLOSE ON EXECVE,所以通常需要输入SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC;protocol指示具体协议,这里我们选用IPPROTO_TCP
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrLen)用于将so ...