转载

libel:C 实现的简单的事件驱动库

libel

An event-driven library.

Libel execute a callback function when a specific event happen on a file descriptor.

install

make config make make install 

use to use

After install libel, you need to add header:

#include<libel/el.h> 

You can compile your code using -lel like this:

gcc -o test test.c -lel 

support

Libel is a multi-platform support library, and now support freeBSD, OS X and linux.

Now libel use kqueue on freebsd, and epoll on linux.

struct

el_loop

An event loop.

event

An event.

api

el_loop *el_loop_new()

create a new event loop.

event *el_event_new(int fd, int flags, void (*cb) (int fd, int size, void *arg), void *arg)

create a new event.

fd : the file descriptor that you want to listen.

flags : READ_EVENT or WRITE_EVENT or both

cb : callback function that will be called by libel

arg : it will be pass to callback function

void el_event_add(el_loop *loop, event *e)

add an event to a loop.

int el_loop_run(el_loop *loop)

To start this event loop.

void el_loop_free(el_loop *loop)

free event loop.

void error(const char *msg)

print msg, errno message and exit(-1).

example

An example of a simple server accept connection from many clients.

server

#include<libel/el.h>  /** create a listener  **/ int create_listener() {   int listenfd;   struct sockaddr_in *servaddr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));   if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)     error("socket error!");   servaddr->sin_family = AF_INET;   servaddr->sin_port = htons(3333);   if (inet_pton(AF_INET, "0.0.0.0", &servaddr->sin_addr) < 0)     error("inet_pton error!");   if (bind(listenfd, (struct sockaddr *)servaddr, sizeof(struct sockaddr_in)) < 0)     error("bind error!");   if (listen(listenfd, LISTENQ) < 0)     error("listen error!");   return listenfd; }  /**     处理客户端发送过来的数据,打印数据。 */ void onread(int fd, int size, void *arg) {   el_loop *loop = (el_loop*)arg;   char buf[MAXLINE];   int n;   while ((n = read(fd, buf, MAXLINE)) > 0) {     buf[n] = '/0';     printf("%s", buf);   }   if (n == 0) {   //客户端已经完成数据的发送。关闭连接。     close(fd);   } else if (n < 0) {     if (errno == EWOULDBLOCK || errno == EAGAIN) {     //如果客户端未发送数据完成,需要继续监听       event *e = el_event_new(fd, READ_EVENT, onread, loop);       el_event_add(loop, e);       return;     } else       error("read from connected socket error!");   } }  /*     处理客户端发起连接的回调函数 */ void onaccept(int fd, int size, void *arg) {   el_loop *loop = (el_loop*)arg;   int i;   //size 为缓冲区中的字节数   for (i = 0; i < size; i++) {     int connfd;     if (( connfd = accept(fd, NULL, NULL)) < 0) {       if (errno == EWOULDBLOCK || errno == ECONNABORTED       || errno == EINTR || errno == EPROTO) {     continue;       } else     error("accept error!");     }     /**         将新建立的连接新建为事件,并加入loop。回调函数为onread。     */     event *e = el_event_new(connfd, READ_EVENT, onread, loop);     el_event_add(loop, e);     /**         在libel的处理机制中,每次事件触发并处理完成后,都会从loop中删除,         所以需要重新创建,并加入loop     */     event *old = el_event_new(fd, READ_EVENT, onaccept, loop);     el_event_add(loop, old);   } }  int main() {   //创建监听   int listenfd = create_listener();   //新建loop   el_loop *loop = el_loop_new();   //新建要监听的事件,回调函数为 onaccept   event *e = el_event_new(listenfd, READ_EVENT, onaccept, loop);   //将要监听的事件注册到loop上   el_event_add(loop, e);   //启动loop   return el_loop_run(loop); }

client

#include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/socket.h> #include<sys/time.h> #include<arpa/inet.h> #include<errno.h> #include<string.h> #define MAX 1024  int main() {   int sockfd;   struct sockaddr_in servaddr;   if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {     fprintf(stderr, "socket error!/n");     exit(-1);   }   servaddr.sin_family = AF_INET;   servaddr.sin_port = htons(3333);   if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) < 0) {     fprintf(stderr, "inet_pton error!/n");     exit(-1);   }   if (connect(sockfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0) {     fprintf(stderr, "connect error!/n");     exit(-1);   }   char buf[MAX];   /**     客户端从终端接收数据,并向服务器端发送。   */   while (fgets(buf, MAX, stdin) != NULL) {     if (write(sockfd, buf, strlen(buf)) < 0) {       fprintf(stderr, "write error!/n");       exit(-1);     }   }   close(sockfd);   return 0; }

Todo

timer , signal , support more system .

原文  https://github.com/luohaha/libel
正文到此结束
Loading...