1*663afb9bSAndroid Build Coastguard Worker /*
2*663afb9bSAndroid Build Coastguard Worker This example program provides a trivial server program that listens for TCP
3*663afb9bSAndroid Build Coastguard Worker connections on port 9995. When they arrive, it writes a short message to
4*663afb9bSAndroid Build Coastguard Worker each client connection, and closes each connection once it is flushed.
5*663afb9bSAndroid Build Coastguard Worker
6*663afb9bSAndroid Build Coastguard Worker Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
7*663afb9bSAndroid Build Coastguard Worker */
8*663afb9bSAndroid Build Coastguard Worker
9*663afb9bSAndroid Build Coastguard Worker
10*663afb9bSAndroid Build Coastguard Worker #include <string.h>
11*663afb9bSAndroid Build Coastguard Worker #include <errno.h>
12*663afb9bSAndroid Build Coastguard Worker #include <stdio.h>
13*663afb9bSAndroid Build Coastguard Worker #include <signal.h>
14*663afb9bSAndroid Build Coastguard Worker #ifndef _WIN32
15*663afb9bSAndroid Build Coastguard Worker #include <netinet/in.h>
16*663afb9bSAndroid Build Coastguard Worker # ifdef _XOPEN_SOURCE_EXTENDED
17*663afb9bSAndroid Build Coastguard Worker # include <arpa/inet.h>
18*663afb9bSAndroid Build Coastguard Worker # endif
19*663afb9bSAndroid Build Coastguard Worker #include <sys/socket.h>
20*663afb9bSAndroid Build Coastguard Worker #endif
21*663afb9bSAndroid Build Coastguard Worker
22*663afb9bSAndroid Build Coastguard Worker #include <event2/bufferevent.h>
23*663afb9bSAndroid Build Coastguard Worker #include <event2/buffer.h>
24*663afb9bSAndroid Build Coastguard Worker #include <event2/listener.h>
25*663afb9bSAndroid Build Coastguard Worker #include <event2/util.h>
26*663afb9bSAndroid Build Coastguard Worker #include <event2/event.h>
27*663afb9bSAndroid Build Coastguard Worker
28*663afb9bSAndroid Build Coastguard Worker static const char MESSAGE[] = "Hello, World!\n";
29*663afb9bSAndroid Build Coastguard Worker
30*663afb9bSAndroid Build Coastguard Worker static const int PORT = 9995;
31*663afb9bSAndroid Build Coastguard Worker
32*663afb9bSAndroid Build Coastguard Worker static void listener_cb(struct evconnlistener *, evutil_socket_t,
33*663afb9bSAndroid Build Coastguard Worker struct sockaddr *, int socklen, void *);
34*663afb9bSAndroid Build Coastguard Worker static void conn_writecb(struct bufferevent *, void *);
35*663afb9bSAndroid Build Coastguard Worker static void conn_eventcb(struct bufferevent *, short, void *);
36*663afb9bSAndroid Build Coastguard Worker static void signal_cb(evutil_socket_t, short, void *);
37*663afb9bSAndroid Build Coastguard Worker
38*663afb9bSAndroid Build Coastguard Worker int
main(int argc,char ** argv)39*663afb9bSAndroid Build Coastguard Worker main(int argc, char **argv)
40*663afb9bSAndroid Build Coastguard Worker {
41*663afb9bSAndroid Build Coastguard Worker struct event_base *base;
42*663afb9bSAndroid Build Coastguard Worker struct evconnlistener *listener;
43*663afb9bSAndroid Build Coastguard Worker struct event *signal_event;
44*663afb9bSAndroid Build Coastguard Worker
45*663afb9bSAndroid Build Coastguard Worker struct sockaddr_in sin = {0};
46*663afb9bSAndroid Build Coastguard Worker #ifdef _WIN32
47*663afb9bSAndroid Build Coastguard Worker WSADATA wsa_data;
48*663afb9bSAndroid Build Coastguard Worker WSAStartup(0x0201, &wsa_data);
49*663afb9bSAndroid Build Coastguard Worker #endif
50*663afb9bSAndroid Build Coastguard Worker
51*663afb9bSAndroid Build Coastguard Worker base = event_base_new();
52*663afb9bSAndroid Build Coastguard Worker if (!base) {
53*663afb9bSAndroid Build Coastguard Worker fprintf(stderr, "Could not initialize libevent!\n");
54*663afb9bSAndroid Build Coastguard Worker return 1;
55*663afb9bSAndroid Build Coastguard Worker }
56*663afb9bSAndroid Build Coastguard Worker
57*663afb9bSAndroid Build Coastguard Worker sin.sin_family = AF_INET;
58*663afb9bSAndroid Build Coastguard Worker sin.sin_port = htons(PORT);
59*663afb9bSAndroid Build Coastguard Worker
60*663afb9bSAndroid Build Coastguard Worker listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
61*663afb9bSAndroid Build Coastguard Worker LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
62*663afb9bSAndroid Build Coastguard Worker (struct sockaddr*)&sin,
63*663afb9bSAndroid Build Coastguard Worker sizeof(sin));
64*663afb9bSAndroid Build Coastguard Worker
65*663afb9bSAndroid Build Coastguard Worker if (!listener) {
66*663afb9bSAndroid Build Coastguard Worker fprintf(stderr, "Could not create a listener!\n");
67*663afb9bSAndroid Build Coastguard Worker return 1;
68*663afb9bSAndroid Build Coastguard Worker }
69*663afb9bSAndroid Build Coastguard Worker
70*663afb9bSAndroid Build Coastguard Worker signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);
71*663afb9bSAndroid Build Coastguard Worker
72*663afb9bSAndroid Build Coastguard Worker if (!signal_event || event_add(signal_event, NULL)<0) {
73*663afb9bSAndroid Build Coastguard Worker fprintf(stderr, "Could not create/add a signal event!\n");
74*663afb9bSAndroid Build Coastguard Worker return 1;
75*663afb9bSAndroid Build Coastguard Worker }
76*663afb9bSAndroid Build Coastguard Worker
77*663afb9bSAndroid Build Coastguard Worker event_base_dispatch(base);
78*663afb9bSAndroid Build Coastguard Worker
79*663afb9bSAndroid Build Coastguard Worker evconnlistener_free(listener);
80*663afb9bSAndroid Build Coastguard Worker event_free(signal_event);
81*663afb9bSAndroid Build Coastguard Worker event_base_free(base);
82*663afb9bSAndroid Build Coastguard Worker
83*663afb9bSAndroid Build Coastguard Worker printf("done\n");
84*663afb9bSAndroid Build Coastguard Worker return 0;
85*663afb9bSAndroid Build Coastguard Worker }
86*663afb9bSAndroid Build Coastguard Worker
87*663afb9bSAndroid Build Coastguard Worker static void
listener_cb(struct evconnlistener * listener,evutil_socket_t fd,struct sockaddr * sa,int socklen,void * user_data)88*663afb9bSAndroid Build Coastguard Worker listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
89*663afb9bSAndroid Build Coastguard Worker struct sockaddr *sa, int socklen, void *user_data)
90*663afb9bSAndroid Build Coastguard Worker {
91*663afb9bSAndroid Build Coastguard Worker struct event_base *base = user_data;
92*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev;
93*663afb9bSAndroid Build Coastguard Worker
94*663afb9bSAndroid Build Coastguard Worker bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
95*663afb9bSAndroid Build Coastguard Worker if (!bev) {
96*663afb9bSAndroid Build Coastguard Worker fprintf(stderr, "Error constructing bufferevent!");
97*663afb9bSAndroid Build Coastguard Worker event_base_loopbreak(base);
98*663afb9bSAndroid Build Coastguard Worker return;
99*663afb9bSAndroid Build Coastguard Worker }
100*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL);
101*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev, EV_WRITE);
102*663afb9bSAndroid Build Coastguard Worker bufferevent_disable(bev, EV_READ);
103*663afb9bSAndroid Build Coastguard Worker
104*663afb9bSAndroid Build Coastguard Worker bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
105*663afb9bSAndroid Build Coastguard Worker }
106*663afb9bSAndroid Build Coastguard Worker
107*663afb9bSAndroid Build Coastguard Worker static void
conn_writecb(struct bufferevent * bev,void * user_data)108*663afb9bSAndroid Build Coastguard Worker conn_writecb(struct bufferevent *bev, void *user_data)
109*663afb9bSAndroid Build Coastguard Worker {
110*663afb9bSAndroid Build Coastguard Worker struct evbuffer *output = bufferevent_get_output(bev);
111*663afb9bSAndroid Build Coastguard Worker if (evbuffer_get_length(output) == 0) {
112*663afb9bSAndroid Build Coastguard Worker printf("flushed answer\n");
113*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev);
114*663afb9bSAndroid Build Coastguard Worker }
115*663afb9bSAndroid Build Coastguard Worker }
116*663afb9bSAndroid Build Coastguard Worker
117*663afb9bSAndroid Build Coastguard Worker static void
conn_eventcb(struct bufferevent * bev,short events,void * user_data)118*663afb9bSAndroid Build Coastguard Worker conn_eventcb(struct bufferevent *bev, short events, void *user_data)
119*663afb9bSAndroid Build Coastguard Worker {
120*663afb9bSAndroid Build Coastguard Worker if (events & BEV_EVENT_EOF) {
121*663afb9bSAndroid Build Coastguard Worker printf("Connection closed.\n");
122*663afb9bSAndroid Build Coastguard Worker } else if (events & BEV_EVENT_ERROR) {
123*663afb9bSAndroid Build Coastguard Worker printf("Got an error on the connection: %s\n",
124*663afb9bSAndroid Build Coastguard Worker strerror(errno));/*XXX win32*/
125*663afb9bSAndroid Build Coastguard Worker }
126*663afb9bSAndroid Build Coastguard Worker /* None of the other events can happen here, since we haven't enabled
127*663afb9bSAndroid Build Coastguard Worker * timeouts */
128*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev);
129*663afb9bSAndroid Build Coastguard Worker }
130*663afb9bSAndroid Build Coastguard Worker
131*663afb9bSAndroid Build Coastguard Worker static void
signal_cb(evutil_socket_t sig,short events,void * user_data)132*663afb9bSAndroid Build Coastguard Worker signal_cb(evutil_socket_t sig, short events, void *user_data)
133*663afb9bSAndroid Build Coastguard Worker {
134*663afb9bSAndroid Build Coastguard Worker struct event_base *base = user_data;
135*663afb9bSAndroid Build Coastguard Worker struct timeval delay = { 2, 0 };
136*663afb9bSAndroid Build Coastguard Worker
137*663afb9bSAndroid Build Coastguard Worker printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");
138*663afb9bSAndroid Build Coastguard Worker
139*663afb9bSAndroid Build Coastguard Worker event_base_loopexit(base, &delay);
140*663afb9bSAndroid Build Coastguard Worker }
141