本文从简单到复杂,展示如何使用libevent。网上的许多例子都是只有服务器端的,本文里面客户端和服务器端都有,以飨读者。
关于libevent编程时的一些疑问可以阅读《libevent编程疑难解答》。假如读者还想了解libevent的具体实现,可以阅读《libevent源码分析》系统文章。
不说这么多了,直接上代码。
初等:
客户端代码:
1 #include<sys/types.h> 2 #include<sys/socket.h> 3 #include<netinet/in.h> 4 #include<arpa/inet.h> 5 #include<errno.h> 6 #include<unistd.h> 7 8 #include<stdio.h> 9 #include<string.h> 10 #include<stdlib.h> 11 12 #include<event.h> 13 #include<event2/util.h> 14 15 16 17 18 int tcp_connect_server(const char* server_ip, int port); 19 20 21 void cmd_msg_cb(int fd, short events, void* arg); 22 void socket_read_cb(int fd, short events, void *arg); 23 24 int main(int argc, char** argv) 25 { 26 if( argc < 3 ) 27 { 28 printf("please input 2 parameter "); 29 return -1; 30 } 31 32 33 //两个参数依次是服务器端的IP地址、端口号 34 int sockfd = tcp_connect_server(argv[1], atoi(argv[2])); 35 if( sockfd == -1) 36 { 37 perror("tcp_connect error "); 38 return -1; 39 } 40 41 printf("connect to server successful "); 42 43 struct event_base* base = event_base_new(); 44 45 struct event *ev_sockfd = event_new(base, sockfd, 46 EV_READ | EV_PERSIST, 47 socket_read_cb, NULL); 48 event_add(ev_sockfd, NULL); 49 50 //监听终端输入事件 51 struct event* ev_cmd = event_new(base, STDIN_FILENO, 52 EV_READ | EV_PERSIST, cmd_msg_cb, 53 (void*)&sockfd); 54 55 56 event_add(ev_cmd, NULL); 57 58 event_base_dispatch(base); 59 60 printf("finished "); 61 return 0; 62 } 63 64 65 66 67 68 69 void cmd_msg_cb(int fd, short events, void* arg) 70 { 71 char msg[1024]; 72 73 int ret = read(fd, msg, sizeof(msg)); 74 if( ret <= 0 ) 75 { 76 perror("read fail "); 77 exit(1); 78 } 79 80 int sockfd = *((int*)arg); 81 82 //把终端的消息发送给服务器端 83 //为了简单起见,不考虑写一半数据的情况 84 write(sockfd, msg, ret); 85 } 86 87 88 void socket_read_cb(int fd, short events, void *arg) 89 { 90 char msg[1024]; 91 92 //为了简单起见,不考虑读一半数据的情况 93 int len = read(fd, msg, sizeof(msg)-1); 94 if( len <= 0 ) 95 { 96 perror("read fail "); 97 exit(1); 98 } 99 100 msg[len] = '