注: client 个人觉得没必要用 libvent来实现就没写
注:由于 涉及到回调函数的使用 如有疑惑的可以先去了解回调函数的实现机理
先来说一下 libevent主要是干啥的 :
内部封装了 socket 通信 和 io 转接函数 ,通过使用大量的回调使得不用考虑大量重复的工作,并且其根据不同平台封装了不同的io转接函数,使其具有跨平台的效果(这里linux 封装的是epoll)
下面 直接上代码 :
1 // File Name: server.c 2 // Author: jiujue 3 // Created Time: 2019年03月29日 星期五 10时11分12秒 4 5 #include<stdio.h> 6 #include<string.h> 7 #include<stdlib.h> 8 #include<time.h> 9 #include<math.h> 10 #include <event2/event.h> 11 #include <event2/bufferevent.h> 12 #include <event2/listener.h> 13 #include <unistd.h> 14 #include <arpa/inet.h> 15 16 //read back call 17 void read_cb(struct bufferevent* bufev,void *ptr) 18 { 19 char buf[1024] = {0}; 20 int len = bufferevent_read(bufev,buf,sizeof(buf)); 21 if(len == -1) 22 { 23 perror("bufferevent_read error"); 24 exit(1); 25 } 26 printf("receive info : %s ",buf); 27 sprintf(buf,"I have received it. "); 28 bufferevent_write(bufev, buf, strlen(buf)+1); 29 30 } 31 //write back call 32 void write_cb(struct bufferevent* bufev,void *ptr) 33 { 34 printf("I sent it out. "); 35 } 36 //event back call 37 void event_cb(struct bufferevent* bufev,short ev, void *ptr) 38 { 39 if(ev & BEV_EVENT_EOF) 40 { 41 printf("have clinet disconnect. "); 42 } 43 if(ev & BEV_EVENT_TIMEOUT) 44 { 45 printf("happen timeout event , exit .... "); 46 exit(1); 47 } 48 bufferevent_free(bufev); 49 } 50 //linsener back call 51 void listener_cb(struct evconnlistener *listener,evutil_socket_t fd, struct sockaddr* addr, int len ,void * ptr) 52 { 53 54 struct event_base *base = (struct event_base*)ptr; 55 struct bufferevent *bufev = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE); 56 bufferevent_setcb(bufev,read_cb,write_cb,event_cb,NULL); 57 bufferevent_enable(bufev,EV_READ); 58 } 59 60 61 int main(int argc, const char* argv[]) 62 { 63 if(argc<2) 64 { 65 printf("argument not enough eg: ./app port"); 66 exit(1); 67 } 68 //event handler frmate 69 struct event_base * base = event_base_new(); 70 //server addr 71 struct sockaddr_in server; 72 server.sin_family = AF_INET; 73 server.sin_addr.s_addr = htonl(INADDR_ANY); 74 server.sin_port = htons(atoi(argv[1])); 75 76 //bind listener accept 77 struct evconnlistener * listener = evconnlistener_new_bind(base,listener_cb,base, 78 LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, 79 (struct sockaddr *)&server, sizeof(server)); 80 81 //start event loop 82 event_base_dispatch(base); 83 84 //collector garbage 85 event_base_free(base); 86 evconnlistener_free(listener); 87 88 89 return 0 ; 90 }
注:如果在libevent库使用的时候出现无法找到动态库的可以百度解决 ;这里提供一种方 分三步 1)找到 libevent.os.xxx 的位置 (一般在/usr/local/ 下 可以是用find命令找一下),2)将刚刚找到文件的绝对路径复制到 /etc/ld.so.conf 文件里 , 3)执行 ldconfig -v 命令可以看到这里刚那个复制的路径已经在里面了;这样就解决了
结语:有问题欢迎提在下方 ,本人在校学生,时间较为充裕, 有时间会回复的。