Skip to content

Instantly share code, notes, and snippets.

@pulsar-git
Created June 24, 2013 15:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pulsar-git/5850952 to your computer and use it in GitHub Desktop.
Save pulsar-git/5850952 to your computer and use it in GitHub Desktop.
/* For sockaddr_in */
#include <netinet/in.h>
/* For socket functions */
#include <sys/socket.h>
/* For fcntl */
#include <fcntl.h>
#include <event2/event.h>
#include <event2/buffer.h>
#include <event2/bufferevent.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define TEST_IP (0x7f000001)
#define TEST_PORT (12345)
static struct timeval write_timeout={
.tv_sec=2,
.tv_usec=0
};
static struct timeval read_timeout={
.tv_sec=5,
.tv_usec=0
};
void
readcb(struct bufferevent *bev, void *ctx)
{
struct evbuffer *input;
input = bufferevent_get_input(bev);
evbuffer_drain(input,evbuffer_get_length(input));
}
void
errorcb(struct bufferevent *bev, short error, void *ctx)
{
//printf("%s: %x\n",__PRETTY_FUNCTION__,error);
if(error & BEV_EVENT_TIMEOUT){
if(error & BEV_EVENT_WRITING){
printf("ERROR! should not get a write timeout");
exit(EXIT_FAILURE);
}
if(error & BEV_EVENT_READING){
printf("Only read timeout good!");
exit(EXIT_SUCCESS);
}
}
}
struct bufferevent *
libevent_connect(struct event_base *base,uint32_t host,int port)
{
struct sockaddr_in sin;
struct bufferevent *bev;
bev = bufferevent_socket_new(base, - 1, BEV_OPT_CLOSE_ON_FREE);
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(host);
sin.sin_port = htons(port);
if (bufferevent_socket_connect(bev,
(struct sockaddr *)&sin, sizeof(sin)) < 0) {
/* Error starting connection */
bufferevent_free(bev);
return NULL;
}
bufferevent_enable(bev, EV_READ|EV_WRITE);
return bev;
}
static enum bufferevent_filter_result
input_filter(struct evbuffer *src, struct evbuffer *dst,
ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx)
{
evbuffer_add_buffer(dst,src);
return BEV_OK;
}
static enum bufferevent_filter_result
output_filter(struct evbuffer *src, struct evbuffer *dst,
ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx)
{
evbuffer_add_buffer(dst,src);
return BEV_OK;
}
void filter_check(struct bufferevent *bev)
{
bev = bufferevent_filter_new(bev, input_filter, output_filter,
BEV_OPT_CLOSE_ON_FREE, NULL, NULL);
bufferevent_setcb(bev, readcb, NULL , errorcb, NULL);
bufferevent_set_timeouts(bev,&read_timeout,&write_timeout);
bufferevent_enable(bev, EV_READ | EV_WRITE);
}
static void
server_accept(evutil_socket_t listener, short event, void *arg)
{
struct event_base *base = arg;
struct sockaddr_storage ss;
socklen_t slen = sizeof(ss);
int fd = accept(listener, (struct sockaddr*)&ss, &slen);
if (fd < 0) {
perror("accept");
} else if (fd > FD_SETSIZE) {
close(fd);
} else {
struct bufferevent *bev;
evutil_make_socket_nonblocking(fd);
bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(bev, readcb, NULL, NULL, NULL);
//bufferevent_setwatermark(bev, EV_READ, 0, MAX_LINE);
bufferevent_enable(bev, EV_READ|EV_WRITE);
}
}
void spawn_server(struct event_base *base)
{
evutil_socket_t listener;
struct sockaddr_in sin;
struct event *listener_event;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = 0;
sin.sin_port = htons(TEST_PORT);
listener = socket(AF_INET, SOCK_STREAM, 0);
evutil_make_socket_nonblocking(listener);
if (bind(listener, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
perror("bind");
return;
}
if (listen(listener, 16)<0) {
perror("listen");
return;
}
listener_event = event_new(base, listener, EV_READ|EV_PERSIST, server_accept, (void*)base);
/*XXX check it */
event_add(listener_event, NULL);
}
void filter_test(struct event_base *base)
{
struct bufferevent *bev,*bev2;
spawn_server(base);
bev2 = libevent_connect(base,TEST_IP,TEST_PORT);
filter_check(bev2);
bev = libevent_connect(base,TEST_IP,TEST_PORT);
bufferevent_setcb(bev, readcb, NULL , errorcb, NULL);
bufferevent_set_timeouts(bev,&read_timeout,&write_timeout);
bufferevent_enable(bev, EV_READ | EV_WRITE);
}
int
libevent_loop(void)
{
struct event_base *base;
base = event_base_new();
if (!base)
return 1;
filter_test(base);
while(1)
event_base_dispatch(base);
return 0;
}
int
main(int c, char **v)
{
setvbuf(stdout, NULL, _IONBF, 0);
libevent_loop();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment