libevent函数库核心思想

/***
epoll_loop.c
***/
#include<stdio.h>
#include<sys/epoll.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>#define MAX_EVENTS 2014
#define BUFLEN 4096
#define SERV_PORT 8080void recvdata(int fd,int events,void *arg);
void senddata(int fd,int events,void *arg);struct myevent_s
{int fd;int events;void *arg;void (*call_back)(int fd,int events,void *arg);int status;char buf[BUFLEN];int len;long last_active;
};int g_efd;
struct myevent_s g_events[MAX_EVENTS + 1];void eventset(struct myevent_s *ev,int fd,void (*call_back)(int,int,void*),void *arg)
{ev->fd = fd;ev->call_back = call_back;ev->events = 0;ev->arg = arg;ev->status = 0;ev->last_active = time(NULL);return;
}void eventadd(int efd,int events,struct myevent_s *ev)
{struct epoll_event epv = {0,{0}};int op;epv.data.ptr = ev;epv.events = ev->events = events;if(ev->status == 1){op = EPOLL_CTL_MOD; }else{op = EPOLL_CTL_ADD;ev->status = 1; }if(epoll_ctl(efd,op,ev->fd,&epv) < 0){printf("event add failed [fd=%d],evens[%d]\n",ev->fd,events) ;}else{printf("event add OK[fd=%d],op = %d,evens[%0X]\n",ev->fd,op,events) ;}return;
}void eventdel(int efd,struct myevent_s *ev)
{struct epoll_event epv = {0,{0}};if(ev->status != 1){return; }epv.data.ptr = ev;ev->status = 0;epoll_ctl(efd,EPOLL_CTL_DEL,ev->fd,&epv);return;
}void acceptconn(int lfd,int events,void *arg)
{struct sockaddr_in cin;socklen_t len = sizeof(cin);int cfd,i;if((cfd = accept(lfd,(struct sockaddr *)&cin,&len)) == -1){if(errno != EAGAIN && errno != EINTR) {}printf("%s : accept,%s \n",__func__,strerror(errno));return ;}do{for(i = 0; i < MAX_EVENTS; i++) {if(g_events[i].status == 0) {break; }}if(i == MAX_EVENTS){printf("%s: max connect limit[%d]\n]",__func__,MAX_EVENTS) ;return;}int flag = 0;if((flag = fcntl(cfd,F_SETFL,O_NONBLOCK)) < 0){printf("%s : accept,%s \n",__func__,strerror(errno));break;}eventset(&g_events[i],cfd,recvdata,&g_events[i]);eventadd(g_efd,EPOLLIN,&g_events[i]);}while(0);printf("new connect [%s:%d][time:%ld],pos[%d]\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),g_events[i].last_active,i);return;
}void recvdata(int fd,int events,void *arg)
{struct myevent_s *ev = (struct myevent_s *)arg;int len;len = recv(fd,ev->buf,sizeof(ev->buf),0);eventdel(g_efd,ev);if(len > 0){ev->len = len;ev->buf[len]  = 0;printf("C[%d]:%s\n",fd,ev->buf);eventset(ev,fd,senddata,ev);eventadd(g_efd,EPOLLOUT,ev);}else if(len == 0){close(ev->fd) ;printf("[fd = %d] pos[%ld],close\n",fd,ev-g_events);}else{close(ev->fd) ;printf("recv[fd=%d] error[%d]:%s\n",fd,errno,strerror(errno));}return;
}void senddata(int fd,int events,void *arg)
{struct myevent_s *ev = (struct myevent_s *)arg;int len;len = send(fd,ev->buf,ev->len,0);if(len > 0){printf("send[fd=%d],[%d]%s\n",fd,len,ev->buf) ;eventdel(g_efd,ev);eventset(ev,fd,recvdata,ev);eventadd(g_efd,EPOLLIN,ev);}else{close(ev->fd) ;eventdel(g_efd,ev);printf("send[fd=%d] error %s\n",fd,strerror(errno));}return;
}void initlistensocket(int efd,short port)
{int lfd = socket(AF_INET,SOCK_STREAM,0);fcntl(lfd,F_SETFL,O_NONBLOCK);eventset(&g_events[MAX_EVENTS],lfd,acceptconn,&g_events[MAX_EVENTS]);eventadd(efd,EPOLLIN,&g_events[MAX_EVENTS]);struct sockaddr_in sin;memset(&sin,0,sizeof(sin));sin.sin_addr.s_addr = INADDR_ANY;sin.sin_family = AF_INET;sin.sin_port = htons(port);bind(lfd,(struct sockaddr*)&sin,sizeof(sin));listen(lfd,20);return ;
}int main(int argc, char *argv[])
{unsigned short port = SERV_PORT;if(argc == 2){port = atoi(argv[1]) ;}g_efd = epoll_create(MAX_EVENTS+1);if(g_efd <= 0){printf("Create efd in %s error %s\n",__func__,strerror(errno)) ;}initlistensocket(g_efd,port);struct epoll_event events[MAX_EVENTS+1];printf("server running:port[%d]\n",port);int checkpos = 0,i;while(1){long now = time(NULL) ;for(i = 0 ; i < 100; i++,checkpos++){if(checkpos == MAX_EVENTS) checkpos = 0;if(g_events[checkpos].status != 1){continue; }long duration = now - g_events[checkpos].last_active;if(duration >= 60){close(g_events[checkpos].fd) ;printf("[fd=%d] timeout\n",g_events[checkpos].fd);eventdel(g_efd,&g_events[checkpos]);}}int nfd = epoll_wait(g_efd,events,MAX_EVENTS+1,1000);if(nfd < 0){printf("epoll_wait error, exit\n") ;break;}for(i = 0; i < nfd; i++){struct myevent_s *ev = (struct myevent_s *)events[i].data.ptr;if((events[i].events & EPOLLIN) && (ev->events & EPOLLIN)){ev->call_back(ev->fd,events[i].events,ev->arg) ;}if((events[i].events & EPOLLOUT) && (ev->events & EPOLLOUT)){ev->call_back(ev->fd,events[i].events,ev->arg);}}}return 0;
}

转载于:https://www.cnblogs.com/wanghao-boke/p/11443231.html

epoll反应堆模型代码相关推荐

  1. Epoll 反应堆模型核心原理及代码讲解

    Epoll 反应堆模型核心原理及代码讲解 [Ⅰ] Epoll 原理及应用 && ET模式与LT模式 [Ⅱ] Epoll 反应堆模型核心原理及代码讲解 一.反应堆核心原理 二.反应堆模型 ...

  2. epoll反应堆模型

    ================================ 下面代码实现的思想:epoll反应堆模型:( libevent 网络编程开源库 核心思想) 1. 普通多路IO转接服务器: 红黑树 ― ...

  3. Linux网络编程7——epoll反应堆模型

    学习视频链接 16-epoll反应堆main逻辑_bilibili_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1iJ411S7UA?p=81& ...

  4. linux C 基于事件回调的epoll反应堆模型

    先看一眼事件声明的结构体 #define MAX_EVENTS 1024 //监听上限数 #define BUFLEN 4096 #define SERV_PORT 8080void recvdata ...

  5. 用Linux / C实现基于自动扩/减容线程池+epoll反应堆检测沉寂用户模型的服务器框架(含源码)

    用Linux/ C实现基于自动扩/减容线程池+epoll反应堆模型的服务器框架 前言 服务器端源码 客户端源码 自定义库 helper.c 和 helper.h helper.c helper.h M ...

  6. epoll服务器反应堆模型

    常规的epoll处理 epoll是io多路复用的一种实现方式,最开始我们使用epoll是对多个fd进行管理,当epoll_wait从内核的rdllist就绪链表中取出一定数量的poll_event时, ...

  7. linux网络编程 epoll水平触发、边沿触发、反应堆模型、线程池思想

    打开文件上限的设置可修改配置文件: etc/security/limits.conf 水平.边沿触发: 若客户端发送1000B数据,服务器一次只读500B.在水平触发的模式下,服务器会再调用一次epo ...

  8. Linux下select, poll和epoll IO模型的详解

    http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll 介绍 Epoll 可是当前在 Linux 下开发大规模并发网络程序的热 ...

  9. 处理大并发之一 对epoll的理解,epoll客户端服务端代码

    http://blog.csdn.net/zhuxiaoping54532/article/details/56494313 处理大并发之一 对epoll的理解,epoll客户端服务端代码 序言: 该 ...

最新文章

  1. 解决Eclipse安装Genymotion插件后抛异常的Bug
  2. 风控项目-收集基础知识1
  3. goland idea设置代码自动换行
  4. java代码输出伞_在伞中集成测试Web应用程序的问题
  5. 2016版单词的减法_在2016年最大的电影中,女性只说了27%的单词。
  6. Qt生成的exe中为什么会带有不该有的盾牌?
  7. 在linux下解压jdk时出现的问题
  8. 针对IE的CSS hack 全面 实用
  9. iso镜像添加软件包_超薄Docker容器-减少Docker镜像大小的指南
  10. Scala进阶之路-进程控制之执行shell脚本
  11. 【linux】nmap命令使用
  12. oracle sqlplus客户端,sqlplus下载|oracle sqlplus windows 客户端工具 64位下载 - 3322软件站...
  13. 卫星系统算法课程设计 - 第一部分:城市时间窗口、间隙等
  14. GitLab Admin Area
  15. 码流格式: Annex-B, AVCC(H.264)与HVCC(H.265), extradata详解
  16. 详解GMT CST UTC DST PDT PST几个时间概念
  17. kal渗透----缓冲区溢出个人笔记
  18. Python机器学习、深度学习库总结
  19. 再谈机器学习中的归一化方法(Normalization Method)
  20. GPU CUDA Python笔记

热门文章

  1. 【UVA 10816】 Travel in Desert (最小瓶颈树+最短路)
  2. dynamic与var
  3. WP8开发学习笔记动态修改启动时导航的第一个页面(如登录前启动页为LoginPage,登录后变为MainPage)...
  4. 万网与阿里巴巴业务关系图解
  5. mysql用户 11_MySQL-快速入门(11)用户管理
  6. php送数据找不到表,php – 数据源默认值中找不到的模型表
  7. android baseactivity,Android应用开发Android通过BaseActivity获取到当前启动的Activity名称...
  8. 中职升高职c语言程序设计教程课后答案,中职C语言教学创新与实践论文
  9. linux vfs open函数,Linux VFS中open系统调用实现原理
  10. java二叉树代码_JAVA语言实现二叉树生成的代码教程