您的位置:首页 > 其它

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

2015-02-04 12:12 561 查看
最近在进行一个基于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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐