Before you can use any interesting Libevent function, you need to allocate one or more event_base structures. Each event_base structure holds a set of events and can poll to determine which events are active.
struct evconnlistener *evconnlistener_new_bind(struct event_base *base,
evconnlistener_cb cb, void *ptr, unsigned flags, int backlog,
const struct sockaddr *sa, int socklen);
evconnlistener_new_bind allocates and returns a new connection listener object. A connection listener uses an event_base to note when there is a new TCP connection on a given listener socket. When a new connection arrives, it invokes the callback function you give it. The ptr pointer will be passed to the callback.
A "bufferevent" consists of an underlying transport (like a socket), a read buffer, and a write buffer.
Every bufferevent has an input buffer and an output buffer. These are of type "struct evbuffer". When you have data to write on a bufferevent, you add it to the output buffer; when a bufferevent has data for you to read, you drain it from the input buffer.
struct bufferevent *bufferevent_socket_new(
struct event_base *base,
evutil_socket_t fd,
enum bufferevent_options options);
Create a socket-based bufferevent using bufferevent_socket_new().
The fd argument is an optional file descriptor for a socket. You can set fd to -1 if you want to set the file descriptor later.
void bufferevent_setcb(struct bufferevent *bufev,
bufferevent_data_cb readcb, bufferevent_data_cb writecb,
bufferevent_event_cb eventcb, void *cbarg);
The bufferevent_setcb() function changes one or more of the callbacks of a bufferevent. The readcb, writecb, and eventcb functions are called (respectively) when enough data is read, when enough data is written, or when an event occurs (like when a connection is launched). You can use the last argument to pass data to your callbacks. The following event flags are defined:
BEV_EVENT_CONNECTED
- We finished a requested connection on the bufferevent.
int bufferevent_socket_connect(struct bufferevent *bev,
struct sockaddr *address, int addrlen);
If the bufferevent’s socket is not yet connected, launch a new connection.
Example:
#include <event2/event.h>
#include <event2/bufferevent.h>
#include <sys/socket.h>
#include <string.h>
void eventcb(struct bufferevent *bev, short events, void *ptr)
{
if (events & BEV_EVENT_CONNECTED) {
/* We're connected to 127.0.0.1:8080. Ordinarily we'd do
something here, like start reading or writing. */
} else if (events & BEV_EVENT_ERROR) {
/* An error occured while connecting. */
}
}
int main_loop(void)
{
struct event_base *base;
struct bufferevent *bev;
struct sockaddr_in sin;
base = event_base_new();
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
sin.sin_port = htons(8080); /* Port 8080 */
bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(bev, NULL, NULL, eventcb, NULL);
if (bufferevent_socket_connect(bev,
(struct sockaddr *)&sin, sizeof(sin)) < 0) {
/* Error starting connection */
bufferevent_free(bev);
return -1;
}
event_base_dispatch(base);
return 0;
}