libevent基础:用libevent写服务端server程序和客户端client程序

最近在进行一个基于libevent的项目,,需要对libevent在socket通讯上的性能进行测试,写了这个简易的server和client程序,这也是libevent的基础,希望对大家了解libevent有所帮助。

使用libevent-2.0.21。

server.c

/************************************ * For msmr * server.c * tesing the speed of bufferevent_write * 2015-02-03 * author@tom************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <event2/event.h>#include <event2/listener.h>#include <event2/bufferevent.h>#include <event2/buffer.h>#include <netinet/tcp.h>static void server_on_read(struct bufferevent* bev,void* arg){struct timeval start_t;gettimeofday(&start_t,NULL);printf("Warning: server_on_read start timestamp %lu.%06lu\n", start_t.tv_sec, start_t.tv_usec);struct evbuffer* input = bufferevent_get_input(bev);size_t len = 0;len = evbuffer_get_length(input);printf("There Is %u Bytes Data In The Buffer In Total.\n",(unsigned)len);// readchar* buf;buf = (char*)malloc(sizeof(char)*len);if(NULL==buf){return;}//evbuffer_copyout(input,buf,len); // it do not clear the input bufferevbuffer_remove(input,buf,len); // clear the bufferprintf("Server gets the message from client: %s\n", buf);// checklen = 0;len = evbuffer_get_length(input);printf("After the first reading, there Is %u Bytes Data Left In The Buffer.\n",(unsigned)len);free(buf);buf=NULL;return;}void server_on_accept(struct evconnlistener* listener,evutil_socket_t fd,struct sockaddr *address,int socklen,void *arg){printf("accept a client : %d\n", fd);// set TCP_NODELAYint enable = 1;if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&enable, sizeof(enable)) < 0)printf("Consensus-side: TCP_NODELAY SETTING ERROR!\n");struct event_base *base = evconnlistener_get_base(listener);struct bufferevent* new_buff_event = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);// bufferevent_setwatermark(new_buff_event, EV_READ, 72, 0);bufferevent_setcb(new_buff_event,server_on_read,NULL,NULL,NULL);// set a read timeout of 1000 us// struct timeval tv = {0, 10000};// bufferevent_set_timeouts(new_buff_event, &tv, NULL);bufferevent_enable(new_buff_event,EV_READ|EV_WRITE);return;}int main(){int port = 9876;struct sockaddr_in my_address;memset(&my_address, 0, sizeof(my_address));my_address.sin_family = AF_INET;my_address.sin_addr.s_addr = htonl(0x7f000001); // 127.0.0.1my_address.sin_port = htons(port);struct event_base* base = event_base_new();struct evconnlistener* listener =evconnlistener_new_bind(base,server_on_accept,NULL,LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,-1,(struct sockaddr*)&my_address,sizeof(my_address));if(!listener)exit(1);event_base_dispatch(base);evconnlistener_free(listener);event_base_free(base);return 0;}

client.c

/************************************ * For msmr * server.c * tesing the speed of bufferevent_write * 2015-02-03 * author@tom************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <event2/event.h>#include <event2/bufferevent.h>#include <event2/buffer.h>#include <netinet/tcp.h>int main(){// build the message to be sentint length = 800; // the size of messagechar* mesg = (char*)malloc((length+1)*sizeof(char)); // Look out the end mark '/0' of a C stringif (mesg == NULL)exit(1);int i;for (i=0; i<length; i++)strcat(mesg, "a");printf("%s\n", mesg);printf("%d\n", (int)strlen(mesg));// build socketint port = 9876;struct sockaddr_in my_address;memset(&my_address, 0, sizeof(my_address));my_address.sin_family = AF_INET;my_address.sin_addr.s_addr = htonl(0x7f000001); // 127.0.0.1my_address.sin_port = htons(port);// build event basestruct event_base* base = event_base_new();// set TCP_NODELAY to let data arrive at the server side quicklyevutil_socket_t fd;fd = socket(AF_INET, SOCK_STREAM, 0);struct bufferevent* conn = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);int enable = 1;if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&enable, sizeof(enable)) < 0)printf("ERROR: TCP_NODELAY SETTING ERROR!\n");//bufferevent_setcb(conn, NULL, NULL, NULL, NULL); // For client, we don't need callback functionbufferevent_enable(conn, EV_WRITE);if(bufferevent_socket_connect(conn,(struct sockaddr*)&my_address,sizeof(my_address)) == 0)printf("connect success\n");// start to send databufferevent_write(conn,mesg,length);// check the output evbufferstruct evbuffer* output = bufferevent_get_output(conn);int len = 0;len = evbuffer_get_length(output);printf("output buffer has %d bytes left\n", len);event_base_dispatch(base);free(mesg);mesg = NULL;bufferevent_free(conn);event_base_free(base);printf("Client program is over\n");return 0;}

Makefile:

#! /bin/bash.PHONY:cleandefault:gcc -O server.c -o server -leventgcc -O client.c -o client -leventclean:rm server client

附上一个更好的牛人写的例子:

https://github.com/bluecloudmatrix/recipes/tree/master/pingpong/libevent

才会看到属于自己的那一片晴朗的天空。

libevent基础:用libevent写服务端server程序和客户端client程序

相关文章:

你感兴趣的文章:

标签云: