文章目录
全文约 8696 字,预计阅读时长: 25分钟
Reactor反应堆模式
Reactor
:负责检测关心的IO事件,当检测到IO事件时,分发给Handlers处理(对数据的读写处理+对数据的分析处理)。epoll ET
工作方式:只支持非阻塞IO文件。
简易的Reactor epoll ET TCP服务器
单进程基于ET非阻塞设计的一个Reactor模式+数据读写+数据分析。
socket封装
监听套接字的创建、绑定、监听、设置非阻塞I/O
#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include<fcntl.h>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
namespace ns_sock
{
enum
{
SOCK_ERR = 2,
BIND_ERR,
LISTEN_ERR
};
const int g_backlog = 5;
struct sock_package
{
static int SockCreate()
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
cerr << "socket failed" << endl;
exit(SOCK_ERR);
}
//设置可以立即重启绑定。
int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
return sock;
}
static void Bind(const int &sock_fd, const uint16_t &port)
{
struct sockaddr_in local;
bzero(&local, sizeof(local));
local.sin_addr.s_addr = INADDR_ANY;
local.sin_port = htons(port);
local.sin_family = AF_INET;
if (bind(sock_fd, (sockaddr *)&local, sizeof(local)) < 0)
{
cerr << "Bind Error" << endl;
exit(BIND_ERR);
}
}
static void Listen(const int &sock_fd)
{
if (listen(sock_fd, g_backlog) < 0)
{
cerr << "Listen Error" << endl;
exit(LISTEN_ERR);
}
}
static void set_noblock(int listen_sk)
{
int ret_sock = fcntl(listen_sk,F_GETFL);
if(ret_sock<0)
{
cerr<<"fcntl error"<<endl;
exit(5);
}
fcntl(listen_sk,F_SETFL,ret_sock | O_NONBLOCK);
}
};
}
epoll。hpp
一:epoll文件描述符的创建,往epoll文件描述里、添加需要关心的I/O文件 、以及关心的I/O文件的事件;检测事件的发生。
二:当前I/O文件的错误回调功能具有:哈希表删除当前的fd值,epoll_del从epoll红黑树中删除该fd节点;最后关闭fd。
三:检测到所有的异常事件发生时,都交付给当前I/O文件的错误回调处理。
四:当检测有事件就绪时应检测当前I/O文件的FD是否还存在。因为可能发送事件触发时,上一秒该文件有异常,从epoll中删除了。
五:具有一个可以让:当前I/O文件读取完毕后,构建发送报文时,可以修改当前该文件的关心事件的功能。因为读事件时一直需要关心的,写事件需要服务器返回数据时开启,发送完毕取消关心。sock文件描述符的反应堆指针,是为了后续可以使用其内部相关功能。
#pragma once
#include <iostream>
#include <sys/epoll.h>
#include <unordered_map>
#include <string>
#include <utility>
#include <unistd.h>
using namespace std;
namespace ns_reactor
{
class reactor_sv;
class sock_pack;
typedef void (*sock_callback)(sock_pack &);//函数指针类型
class sock_pack//sock_fd配套设施。
{
public