libevent是用c寫的高併發網絡io庫,只要有文件描述符,就均可使用libevent。c++
libevent使用回調函數(callback) 。編程
利用FIFO的進程間通訊read端:微信
#include <event2/event.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define MYFIFO "myfifo" //call back void readcb(evutil_socket_t fd, short what, void* arg){ //read fifo char buf[24] = {0}; int len = read(fd, buf, sizeof(buf)); buf[len] = '\0'; printf("data len = %d, buf = %s\n", len, buf); printf("read event:%s\n", what & EV_READ ? "Yes" : "No"); } int main(){ unlink(MYFIFO); mkfifo(MYFIFO, 0664); int fd = open(MYFIFO, O_RDONLY | O_NONBLOCK); //int fd = open(MYFIFO, O_RDONLY); struct event_base* base; base = event_base_new(); //create event struct event* ev = NULL; ev = event_new(base, fd, EV_READ | EV_PERSIST | EV_ET, readcb, NULL); //add event event_add(ev, NULL); //start event_base_dispatch(base); //free event event_free(ev); event_base_free(base); close(fd); return 0; }
利用FIFO的進程間通訊write端:網絡
#include <event2/event.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #define MYFIFO "myfifo" //call back void writecb(evutil_socket_t fd, short what, void* arg){ //write fifo char buf[24] = {0}; static int num = 0; sprintf(buf, "num = %d", num++); write(fd, buf, strlen(buf) + 1); } int main(){ int fd = open(MYFIFO, O_WRONLY | O_NONBLOCK); struct event_base* base; base = event_base_new(); //create event struct event* ev = NULL; ev = event_new(base, fd, EV_WRITE | EV_PERSIST | EV_ET, writecb, NULL); //add event event_add(ev, NULL); //start event_base_dispatch(base); //free event event_free(ev); event_base_free(base); close(fd); return 0; }
server端:併發
#include <event2/event.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <event2/bufferevent.h> #include <arpa/inet.h> #include <stdlib.h> #include <event2/listener.h> //write callback void write_cb(struct bufferevent* bev, void* ctx){ printf("all is sent\n"); } //read callback void read_cb(struct bufferevent *bev, void *ctx){ char buf[64]; size_t ret = bufferevent_read(bev, buf, sizeof(buf)); buf[ret] = '\0'; printf("server recf:%s\n", buf); bufferevent_write(bev, "hahaha", 6); } //event callback void event_cb(struct bufferevent *bev, short what, void *ctx){ if(what & BEV_EVENT_EOF){ printf("EOF\n"); } if(what & BEV_EVENT_CONNECTED){ printf("connected\n"); } } //listener call back void listencb(struct evconnlistener* listener, evutil_socket_t fd, struct sockaddr* cli, int len, void* ptr){ struct event_base* base = evconnlistener_get_base(listener); struct bufferevent* bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); //set callback function bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL); bufferevent_enable(bev, EV_READ | EV_WRITE); //set water bufferevent_setwatermark(bev, EV_READ, 10, 0); bufferevent_setwatermark(bev, EV_WRITE, 1, 2); } int main(int argc, char** argv){ int port = atoi(argv[1]); struct event_base* base; base = event_base_new(); if(!base){ perror("event_base_new"); exit(1); } struct sockaddr_in s; s.sin_family = AF_INET; s.sin_port = htons(port); s.sin_addr.s_addr = htonl(INADDR_ANY); struct evconnlistener* listener = evconnlistener_new_bind(base, listencb, NULL, LEV_OPT_CLOSE_ON_FREE, -1, (struct sockaddr*)&s, sizeof(s)); if(!listener){ perror("bind"); exit(1); } event_base_dispatch(base); event_base_free(base); }
client端:socket
#include <event2/event.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <event2/bufferevent.h> #include <arpa/inet.h> #include <stdlib.h> #include <event2/listener.h> #include <event2/dns.h> #include <stdlib.h> #include <event2/util.h> //read write callback void readcb(struct bufferevent *bev, void *ctx){ char buf[64]; size_t ret = bufferevent_read(bev, buf, sizeof(buf)); buf[ret] = '\0'; printf("client recf:%s\n", buf); } //event callback void eventcb(struct bufferevent *bev, short what, void *ctx){ if(what & BEV_EVENT_CONNECTED){ printf("connect okay\n"); } else if(what & BEV_EVENT_ERROR){ struct event_base* base = ctx; int err = bufferevent_socket_get_dns_error(bev); if(err){ printf("DNS error:%s\n", evutil_gai_strerror(err)); } printf("closing\n"); bufferevent_free(bev); event_base_loopexit(base, NULL); } } //terminal read callback void termicb(evutil_socket_t fd, short what, void* ptr){ char buf[64] = {0}; int len = read(fd, buf, sizeof(buf)); buf[len] = '\0'; printf("in termicb\n"); struct bufferevent* bev = ptr; bufferevent_write(bev, buf, len); } int main(int artc, char** argv){ struct event_base* base; base = event_base_new(); struct evdns_base* dns_base; dns_base = evdns_base_new(base, 1); struct bufferevent* bev; bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); int port = atoi(argv[2]); bufferevent_setcb(bev, readcb, NULL, eventcb, base); bufferevent_enable(bev, EV_READ); bufferevent_socket_connect_hostname(bev, dns_base, AF_INET, argv[1], port); struct event* ev = event_new(base, STDIN_FILENO, EV_READ | EV_PERSIST, termicb, bev); event_add(ev, NULL); event_base_dispatch(base); event_base_free(base); }