最近在进行一个基于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);
// read
char* buf;
buf = (char*)malloc(sizeof(char)*len);
if(NULL==buf){return;}
//evbuffer_copyout(input,buf,len); // it do not clear the input buffer
evbuffer_remove(input,buf,len); // clear the buffer
printf("Server gets the message from client: %s\n", buf);
// check
len = 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_NODELAY
int 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.1
my_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 sent
int length = 800; // the size of message
char* mesg = (char*)malloc((length+1)*sizeof(char)); // Look out the end mark '/0' of a C string
if (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 socket
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.1
my_address.sin_port = htons(port);
// build event base
struct event_base* base = event_base_new();
// set TCP_NODELAY to let data arrive at the server side quickly
evutil_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 function
bufferevent_enable(conn, EV_WRITE);
if(bufferevent_socket_connect(conn,(struct sockaddr*)&my_address,sizeof(my_address)) == 0)
printf("connect success\n");
// start to send data
bufferevent_write(conn,mesg,length);
// check the output evbuffer
struct 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:clean default: gcc -O server.c -o server -levent gcc -O client.c -o client -levent clean: rm server client
附上一个更好的牛人写的例子:
https://github.com/bluecloudmatrix/recipes/tree/master/pingpong/libevent
libevent基础:用libevent写服务端server程序和客户端client程序
原文:http://blog.csdn.net/bluecloudmatrix/article/details/43484347