sevencat封装的Epoll模型

本文介绍了一个基于Epoll机制的服务器实现案例,详细解释了Epoll的创建、事件处理及客户端会话管理等核心功能,并提供了具体的代码实现。

#pragma once
#include <errno.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "log.h"

#ifndef EPOLL_SIZE
#define EPOLL_SIZE 4096
#define EPOLL_CONTEXT_SIZE (4096+256)
#endif

typedef void * EPollerContext;
class Epoller
{
public:
Epoller(){}
virtual ~Epoller(){}
bool create()
{
 memset(_contexts,0,sizeof(_contexts));
 _handle=epoll_create(EPOLL_SIZE);
 if(_handle==-1)
 {
  glog.log(__FUNCTION__,"Epoll create error,errno is %d",errno);
  return false;
 }
 else
  return true;
}
void handle_events()
{
 for(int i=0;i<_lastntfd;i++)
 {
  on_event(_events[i].data.fd,_events[i].events);
 }
}
int get_online_users()
{
 int result=0;
 for(int i=0;i<EPOLL_CONTEXT_SIZE;i++)
 {
  if(_contexts[i]!=0)
   result++;
 }
 return result;
}
public:
bool add(int fd,unsigned int events)
{
 epoll_event polevt;
 polevt.events=events;
 polevt.data.fd=fd;
 return ctl(EPOLL_CTL_ADD,fd,polevt)==0;
}
bool del(int fd,unsigned int events)
{
 epoll_event polevt;
 polevt.events=events;
 polevt.data.fd=fd;
 return ctl(EPOLL_CTL_DEL,fd,polevt)==0;
}
bool modify(int fd,unsigned int events)
{
 epoll_event polevt;
 polevt.events=events;
 polevt.data.fd=fd;
 return ctl(EPOLL_CTL_MOD,fd,polevt)==0;
}
int poll(int timeout=5000)
{
 _lastntfd=epoll_wait(_handle,_events,EPOLL_SIZE,timeout);
 return _lastntfd;
}
protected:
int ctl(int op, int fd, struct epoll_event &event)
{
 int ret=epoll_ctl(_handle,op,fd,&event);
 if(ret!=0)
 {
  glog.log(__FUNCTION__,"epoll_ctl fail,op is %d,fd is %d,errno is %d",op,fd,errno);
 }
 return ret;
}
protected:
static bool setnonblocking(int sock)
{
 int opts;
 opts=fcntl(sock,F_GETFL);
 if(opts<0)
  opts=O_NONBLOCK;
 else
  opts = opts|O_NONBLOCK;
 if(fcntl(sock,F_SETFL,opts)<0)
 {
  glog.log(__FUNCTION__,"setnoblock error");
  return false;
 }
 else
  return true;
}

static bool setreuseport(int sock)
{
 int on=1;
 int ret=setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(int));
 return ret!=-1;
}



protected:
virtual void on_event(int fd,int events){}
private:
int _handle;
epoll_event _events[EPOLL_SIZE];
int _lastntfd;
protected:
EPollerContext _contexts[EPOLL_CONTEXT_SIZE];
EPollerContext get_context(int value)
{
 return _contexts[value];
}
bool set_context(int value,EPollerContext context)
{
 _contexts[value]=context;
}
};








class ExampleServer : public Epoller
{
public:
bool init();
void fini();
void check_timeout();
protected:
void on_event(int fd,int events);
private:
void add_newsock(int sockvalue);
void remove_sock(int sockvalue);
private:
int _listen_handler;
};





#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "server.h"
#include "clientmanager.h"

bool ExampleServer::init()
{
this->create();
_listen_handler=socket(AF_INET,SOCK_STREAM,0);
setnonblocking(_listen_handler);
setreuseport(_listen_handler);
sockaddr_in serveraddr;
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
serveraddr.sin_port=htons(ITEMLIST_SERVER_PORT);
bind(_listen_handler,(sockaddr *)&serveraddr, sizeof(serveraddr));
listen(_listen_handler,ITEMCOMMENT_SERVER_LISTEN_BACKLOG);
this->add(_listen_handler,EPOLLIN|EPOLLOUT);
this->set_context(_listen_handler,0);
}

void ExampleServer::fini()
{
close(_listen_handler);
}

void ExampleServer::add_newsock(int sockvalue)
{
if(sockvalue>EPOLL_CONTEXT_SIZE)
{
 glog.log(__FUNCTION__,"newsock is %d,> %d",sockvalue,EPOLL_CONTEXT_SIZE);
 close(sockvalue);
 return;
}

ClientSession *newsession=gClientManager.alloc_client_session(sockvalue);
if(newsession==NULL)
{
 close(sockvalue);
 return;
}
if(add(sockvalue,EPOLLIN|EPOLLOUT))
{
 this->set_context(sockvalue,newsession);
}
else
{
 gClientManager.release_client(newsession);
 close(sockvalue);     
}
}

void ExampleServer::remove_sock(int sockvalue)
{
this->del(sockvalue,0);
close(sockvalue);
ClientSession *client=(ClientSession *)this->get_context(sockvalue);
if(client)
{
 gClientManager.release_client(client);
}
this->set_context(sockvalue,0);
}

void ExampleServer::on_event(int fd,int events)
{
if(fd==_listen_handler)
{
 sockaddr_in sa;
 memset(&sa,0,sizeof(sa));
 socklen_t salen=sizeof(sa);
 int newsock=accept(_listen_handler,(sockaddr *)&sa,&salen);
 if(newsock>0)
 {
  add_newsock(newsock);
 }
}
else
{
 ClientSession *client=(ClientSession *)this->get_context(fd);
 if(client!=NULL)
 {
  int newevents=client->handle_events(fd,events);
  if(newevents==0)
  {
   remove_sock(fd);
  }
  else
   this->modify(fd,newevents);
 }
}
}


void ExampleServer::check_timeout()
{
unsigned int curtime=time(NULL);
for(int i=0;i<EPOLL_SIZE+256;i++)
{
 ClientSession *client=(ClientSession *)this->get_context(i);
 if(client!=NULL)
 {
  if(curtime-client->get_last_io_time()>ITEMINDEX_SERVER_MAX_TIMEOUT)
  {
   remove_sock(i);
  }
 }
}
}

计及光伏电站快速无功响应特性的分布式电源优化配置方法(Matlab代码实现)内容概要:本文提出了一种计及光伏电站快速无功响应特性的分布式电源优化配置方法,并提供了基于Matlab的代码实现。该方法在传统分布式电源配置基础上,充分考虑了光伏电站通过逆变器实现的快速无功调节能力,以提升配电网的电压稳定性与运行效率。通过建立包含有功、无功协调优化的数学模型,结合智能算法求解最优电源配置方案,有效降低了网络损耗,改善了节点电压质量,增强了系统对可再生能源的接纳能力。研究案例验证了所提方法在典型配电系统中的有效性与实用性。; 适合人群:具备电力系统基础知识和Matlab编程能力的电气工程专业研究生、科研人员及从事新能源并网、配电网规划的相关技术人员。; 使用场景及目标:①用于分布式光伏等新能源接入配电网的规划与优化设计;②提升配电网电压稳定性与电能质量;③研究光伏逆变器无功补偿能力在系统优化中的应用价值;④为含高比例可再生能源的主动配电网提供技术支持。; 阅读建议:建议读者结合Matlab代码与算法原理同步学习,重点理解目标函数构建、约束条件设定及优化算法实现过程,可通过修改系统参数和场景设置进行仿真对比,深入掌握方法的核心思想与工程应用潜力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值