本文实现的为单reactor 多线程(base)
非核心库
InetAddress
这个库简单而言 无疑是设置ip地址和端口
cpp
class InetAddress
{
public:
struct sockaddr_in addr;
socklen_t addr_len;
InetAddress();
InetAddress(const char* ip, uint16_t port);
~InetAddress();
};
具体而言:
- InetAddress(const char* ip, uint16_t port); 这个无疑是bind函数
- InetAddress(); 这个无疑是accept函数 (connect 客户端 函数将自己系统分配ip和端口)
socket库
这个库实现的网络的绑定
cpp
class InetAddress;
class Socket
{
private:
int fd;
public:
Socket();
Socket(int);
~Socket();
void bind(InetAddress*);
void listen();
void setnonblocking();
int accept(InetAddress*);
int getFd();
};
Epoll库和Channel库
实现io复用以及文件描述符将由channel替代(ev.data.ptr 决定)
class Epoll
{
private:
int epfd;
struct epoll_event *events;
public:
Epoll();
~Epoll();
void addFd(int fd, uint32_t op);
void updateChannel(Channel*);
// std::vector<epoll_event> poll(int timeout = -1);
std::vector<Channel*> poll(int timeout = -1);
};
- epfd 为注册事件表返回的文件操作符
- event :这个其实是等待序列 (内部用new方法实现了)(思考堆和栈的容量大小就知道了)
- 这个addfd和updateChannel内部都实现了注册事件组
- poll函数 返回了一个就绪vector 即检测的channel 基于事件检测 (把相应的文件符对应的Channel放入数组 方便操作)
cpp
class EventLoop;
class Channel
{
private:
EventLoop *loop;
int fd;
uint32_t events;
uint32_t revents;
bool inEpoll;
std::function<void()> callback;
public:
Channel(EventLoop *_loop, int _fd);
~Channel();
void handleEvent();
void enableReading();
int getFd();
uint32_t getEvents();
uint32_t getRevents();
bool getInEpoll();
void setInEpoll();
// void setEvents(uint32_t);
void setRevents(uint32_t);
void setCallback(std::function<void()>);
};
- Eventloop:reactor中事件检测(即epoll_wait)
- fd:相应的文件操作符
- events:events表示希望监听这个文件描述符的哪些事件
- uint32_t revents;//文件描述符正在发生的事件
- bool inEpoll;//当前的channel是否在事件表(那个红黑树)
- std::function<void()> callback; 这个也可说是回调函数(但是会等待执行)
核心库
EventLoop库
这个就是reactor中的事件驱动的原理
class Epoll;
class Channel;
class EventLoop
{
private:
Epoll *ep;
bool quit;
public:
EventLoop();
~EventLoop();
void loop();
void updateChannel(Channel*);
};
cpp
void EventLoop::loop(){
while(!quit){
std::vector<Channel*> chs;
chs = ep->poll();
for(auto it = chs.begin(); it != chs.end(); ++it){
(*it)->handleEvent();
}
}
}
工作原理:首先loop启动,epoll_wait不断的查询就绪的事件并返回就绪的channel.
Server库
cpp
class EventLoop;
class Socket;
class Server
{
private:
EventLoop *loop;
public:
Server(EventLoop*);
~Server();
void handleReadEvent(int);
void newConnection(Socket *serv_sock);
};
这个库然后根据连接还是业务处理(echo函数)进行调用channel的回调函数