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 8080 void 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 + ]; 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 = ;
ev->arg = arg;
ev->status = ;
ev->last_active = time(NULL);
return;
} void eventadd(int efd,int events,struct myevent_s *ev)
{
struct epoll_event epv = {,{}};
int op;
epv.data.ptr = ev;
epv.events = ev->events = events; if(ev->status == )
{
op = EPOLL_CTL_MOD;
}
else
{
op = EPOLL_CTL_ADD;
ev->status = ;
} if(epoll_ctl(efd,op,ev->fd,&epv) < )
{
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 = {,{}}; if(ev->status != )
{
return;
} epv.data.ptr = ev;
ev->status = ;
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)) == -)
{
if(errno != EAGAIN && errno != EINTR)
{ }
printf("%s : accept,%s \n",__func__,strerror(errno));
return ;
} do
{
for(i = ; i < MAX_EVENTS; i++)
{
if(g_events[i].status == )
{
break;
}
} if(i == MAX_EVENTS)
{
printf("%s: max connect limit[%d]\n]",__func__,MAX_EVENTS) ;
return;
} int flag = ;
if((flag = fcntl(cfd,F_SETFL,O_NONBLOCK)) < )
{
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(); 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),); eventdel(g_efd,ev); if(len > )
{
ev->len = len;
ev->buf[len] = ;
printf("C[%d]:%s\n",fd,ev->buf); eventset(ev,fd,senddata,ev);
eventadd(g_efd,EPOLLOUT,ev);
}
else if(len == )
{
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,); if(len > )
{
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,);
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,,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,);
return ;
} int main(int argc, char *argv[])
{
unsigned short port = SERV_PORT; if(argc == )
{
port = atoi(argv[]) ;
} g_efd = epoll_create(MAX_EVENTS+);
if(g_efd <= )
{
printf("Create efd in %s error %s\n",
__func__,strerror(errno)) ;
}
initlistensocket(g_efd,port); struct epoll_event events[MAX_EVENTS+];
printf("server running:port[%d]\n",port); int checkpos = ,i;
while()
{
long now = time(NULL) ;
for(i = ; i < ; i++,checkpos++)
{
if(checkpos == MAX_EVENTS)
checkpos = ;
if(g_events[checkpos].status != )
{
continue;
} long duration = now - g_events[checkpos].last_active; if(duration >= )
{
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+,);
if(nfd < )
{
printf("epoll_wait error, exit\n") ;
break;
} for(i = ; 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 ;
}

epoll反应堆模型代码的更多相关文章

  1. epoll反应堆模型

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

  2. epoll反应堆模型实现

    epoll反应堆模型demo实现 在高并发TCP请求中,为了实现资源的节省,效率的提升,Epoll逐渐替代了之前的select和poll,它在用户层上规避了忙轮询这种效率不高的监听方式,epoll的时 ...

  3. epoll原理详解及epoll反应堆模型

    本文转载自epoll原理详解及epoll反应堆模型 导语 设想一个场景:有100万用户同时与一个进程保持着TCP连接,而每一时刻只有几十个或几百个TCP连接是活跃的(接收TCP包),也就是说在每一时刻 ...

  4. epoll 反应堆

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

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

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

  6. (转)Linux下select, poll和epoll IO模型的详解

    Linux下select, poll和epoll IO模型的详解 原文:http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll ...

  7. Windows Socket五种I/O模型——代码全攻略(转)

    Winsock 的I/O操作: 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序.套接字 默认为阻塞模式.可以通过多线程技术进行处理. 非阻塞模式:执行I/O操 ...

  8. 多路复用I/O模型poll() 模型 代码实现

    多路复用I/O模型poll() 模型 代码实现 poll()机制和select()机制是相似的,都是对多个描述符进行轮询的方式. 不同的是poll()没有描述符数目的限制. 是通过struct pol ...

  9. Matlab 图论最短路问题模型代码

    最短路问题的基本内容 最短路问题研究的是,在一个点与点之间连接形成的网络图中,对应路径赋予一定的权重(可以理解为两点之间的距离),计算任意两点之间如何和走,路径最短的问题.在这里的距离可以理解成各种两 ...

随机推荐

  1. Consul作为SpringCloud配置中心

    一.背景介绍 在分布式系统中动态配置中,可以避免重复重启服务,动态更改服务参数等.一句话非常重要. 另外一篇文章也是这样说的,哈哈. Consul 作为Spring 推荐的分布式调度系统其也具备配置中 ...

  2. Windows终端命令行工具Cmder

    在IT这一行,大部分情况下都是推荐大家使用Linux或者类Unix操作系统去编程,Linux作为一代优秀的操作系统,已经人尽皆知,在IT行业已经成为核心.有条件的大佬都选择了使用mac编程,最优秀的莫 ...

  3. [转载]Linux下非root用户如何安装软件

    [转载]Linux下非root用户如何安装软件 来源:https://tlanyan.me/work-with-linux-without-root-permission/ 这是本人遇到的实际问题,之 ...

  4. selenium2自动化测试实战--基于Python语言

    自动化测试基础 一. 软件测试分类 1.1 根据项目流程阶段划分软件测试 1.1.1 单元测试 单元测试(或模块测试)是对程序中的单个子程序或具有独立功能的代码段进行测试的过程. 1.1.2 集成测试 ...

  5. H5表单新特性

    1.HTML5表单新特性之——新的input type <input type=" "> HTML5之前已有的input type: text.password.rad ...

  6. body onload()事件和table insertRow()、tr insertCell()

    onload事件: 定义和用法: onload 事件会在页面或图像加载完成后立即发生. onload 通常用于 <body> 元素,在页面完全载入后(包括图片.css文件等等.)执行脚本代 ...

  7. 【js】字符串反转(倒序)的多种处理方式

    今天发布一篇关于字符串反转的几种方式(一种问题的解决方案不是只有一种). 方式1: 这种方式比较简单,推荐使用 字符串转数组,反转数组,数组转字符串. split(""):根据空字 ...

  8. angular-cli 引入ui组件库

    该例中使用的admin-lte以及bootstrap 1.使用npm 安装admin-lte命令: npm install admin-lte --save  (--save的意思是将该以来写入到pa ...

  9. ubuntu18.04 安装idea

    首先从官网下载idea:IntelliJ IDEA    (在安装IDEA前应先安装jdk环境) 得到ideaIU-2019.2.4.tar.gz 将安装包移动到/usr/local,这样可以让所有用 ...

  10. 无法写入配置文件...需要在IIS中手动创建此虚拟目录,才可以打开此项目

    无妄之灾   之前闲着没事写了一个webapi项目,今天下了班闲来无事就像拿出来改改,没想到打开的时候就提示出现错误. 没错就是这货,其实也不是第一次遇见这个问题了,但是之前一直没有找到解决方案,在网 ...