1 /* $NetBSD: hello-world.c,v 1.1.1.1 2013/04/11 16:43:31 christos Exp $ */
3 This exmple program provides a trivial server program that listens for TCP
4 connections on port 9995. When they arrive, it writes a short message to
5 each client connection, and closes each connection once it is flushed.
7 Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
16 #include <netinet/in.h>
17 # ifdef _XOPEN_SOURCE_EXTENDED
18 # include <arpa/inet.h>
20 #include <sys/socket.h>
23 #include <event2/bufferevent.h>
24 #include <event2/buffer.h>
25 #include <event2/listener.h>
26 #include <event2/util.h>
27 #include <event2/event.h>
29 static const char MESSAGE
[] = "Hello, World!\n";
31 static const int PORT
= 9995;
33 static void listener_cb(struct evconnlistener
*, evutil_socket_t
,
34 struct sockaddr
*, int socklen
, void *);
35 static void conn_writecb(struct bufferevent
*, void *);
36 static void conn_eventcb(struct bufferevent
*, short, void *);
37 static void signal_cb(evutil_socket_t
, short, void *);
40 main(int argc
, char **argv
)
42 struct event_base
*base
;
43 struct evconnlistener
*listener
;
44 struct event
*signal_event
;
46 struct sockaddr_in sin
;
49 WSAStartup(0x0201, &wsa_data
);
52 base
= event_base_new();
54 fprintf(stderr
, "Could not initialize libevent!\n");
58 memset(&sin
, 0, sizeof(sin
));
59 sin
.sin_family
= AF_INET
;
60 sin
.sin_port
= htons(PORT
);
62 listener
= evconnlistener_new_bind(base
, listener_cb
, (void *)base
,
63 LEV_OPT_REUSEABLE
|LEV_OPT_CLOSE_ON_FREE
, -1,
64 (struct sockaddr
*)&sin
,
68 fprintf(stderr
, "Could not create a listener!\n");
72 signal_event
= evsignal_new(base
, SIGINT
, signal_cb
, (void *)base
);
74 if (!signal_event
|| event_add(signal_event
, NULL
)<0) {
75 fprintf(stderr
, "Could not create/add a signal event!\n");
79 event_base_dispatch(base
);
81 evconnlistener_free(listener
);
82 event_free(signal_event
);
83 event_base_free(base
);
90 listener_cb(struct evconnlistener
*listener
, evutil_socket_t fd
,
91 struct sockaddr
*sa
, int socklen
, void *user_data
)
93 struct event_base
*base
= user_data
;
94 struct bufferevent
*bev
;
96 bev
= bufferevent_socket_new(base
, fd
, BEV_OPT_CLOSE_ON_FREE
);
98 fprintf(stderr
, "Error constructing bufferevent!");
99 event_base_loopbreak(base
);
102 bufferevent_setcb(bev
, NULL
, conn_writecb
, conn_eventcb
, NULL
);
103 bufferevent_enable(bev
, EV_WRITE
);
104 bufferevent_disable(bev
, EV_READ
);
106 bufferevent_write(bev
, MESSAGE
, strlen(MESSAGE
));
110 conn_writecb(struct bufferevent
*bev
, void *user_data
)
112 struct evbuffer
*output
= bufferevent_get_output(bev
);
113 if (evbuffer_get_length(output
) == 0) {
114 printf("flushed answer\n");
115 bufferevent_free(bev
);
120 conn_eventcb(struct bufferevent
*bev
, short events
, void *user_data
)
122 if (events
& BEV_EVENT_EOF
) {
123 printf("Connection closed.\n");
124 } else if (events
& BEV_EVENT_ERROR
) {
125 printf("Got an error on the connection: %s\n",
126 strerror(errno
));/*XXX win32*/
128 /* None of the other events can happen here, since we haven't enabled
130 bufferevent_free(bev
);
134 signal_cb(evutil_socket_t sig
, short events
, void *user_data
)
136 struct event_base
*base
= user_data
;
137 struct timeval delay
= { 2, 0 };
139 printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");
141 event_base_loopexit(base
, &delay
);