franta-hg@28
|
1 |
#include <string.h>
|
franta-hg@28
|
2 |
#include <errno.h>
|
franta-hg@28
|
3 |
#include <stdio.h>
|
franta-hg@28
|
4 |
#include <signal.h>
|
franta-hg@28
|
5 |
|
franta-hg@28
|
6 |
#include <event2/bufferevent.h>
|
franta-hg@28
|
7 |
#include <event2/buffer.h>
|
franta-hg@28
|
8 |
#include <event2/listener.h>
|
franta-hg@28
|
9 |
#include <event2/util.h>
|
franta-hg@28
|
10 |
#include <event2/event.h>
|
franta-hg@28
|
11 |
|
franta-hg@28
|
12 |
static const char MESSAGE[] = "Hello, World!\n";
|
franta-hg@28
|
13 |
|
franta-hg@28
|
14 |
static const int PORT = 9995;
|
franta-hg@28
|
15 |
|
franta-hg@28
|
16 |
static void listener_cb(struct evconnlistener *, evutil_socket_t,
|
franta-hg@28
|
17 |
struct sockaddr *, int socklen, void *);
|
franta-hg@28
|
18 |
static void conn_write_cb(struct bufferevent *, void *);
|
franta-hg@28
|
19 |
static void conn_event_cb(struct bufferevent *, short, void *);
|
franta-hg@28
|
20 |
static void signal_cb(evutil_socket_t, short, void *);
|
franta-hg@28
|
21 |
|
franta-hg@28
|
22 |
int main(int argc, char **argv) {
|
franta-hg@28
|
23 |
struct event_base *base;
|
franta-hg@28
|
24 |
struct evconnlistener *listener;
|
franta-hg@28
|
25 |
struct event *signal_event;
|
franta-hg@28
|
26 |
|
franta-hg@28
|
27 |
struct sockaddr_in sin;
|
franta-hg@28
|
28 |
|
franta-hg@28
|
29 |
base = event_base_new();
|
franta-hg@28
|
30 |
if (!base) {
|
franta-hg@28
|
31 |
fprintf(stderr, "Could not initialize libevent!\n");
|
franta-hg@28
|
32 |
return 1;
|
franta-hg@28
|
33 |
}
|
franta-hg@28
|
34 |
|
franta-hg@28
|
35 |
memset(&sin, 0, sizeof (sin));
|
franta-hg@28
|
36 |
sin.sin_family = AF_INET;
|
franta-hg@28
|
37 |
sin.sin_port = htons(PORT);
|
franta-hg@28
|
38 |
|
franta-hg@28
|
39 |
listener = evconnlistener_new_bind(base, listener_cb, (void *) base,
|
franta-hg@28
|
40 |
LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1,
|
franta-hg@28
|
41 |
(struct sockaddr*) &sin,
|
franta-hg@28
|
42 |
sizeof (sin));
|
franta-hg@28
|
43 |
|
franta-hg@28
|
44 |
if (!listener) {
|
franta-hg@28
|
45 |
fprintf(stderr, "Could not create a listener!\n");
|
franta-hg@28
|
46 |
return 1;
|
franta-hg@28
|
47 |
}
|
franta-hg@28
|
48 |
|
franta-hg@28
|
49 |
signal_event = evsignal_new(base, SIGINT, signal_cb, (void *) base);
|
franta-hg@28
|
50 |
|
franta-hg@28
|
51 |
if (!signal_event || event_add(signal_event, NULL) < 0) {
|
franta-hg@28
|
52 |
fprintf(stderr, "Could not create/add a signal event!\n");
|
franta-hg@28
|
53 |
return 1;
|
franta-hg@28
|
54 |
}
|
franta-hg@28
|
55 |
|
franta-hg@28
|
56 |
event_base_dispatch(base);
|
franta-hg@28
|
57 |
|
franta-hg@28
|
58 |
evconnlistener_free(listener);
|
franta-hg@28
|
59 |
event_free(signal_event);
|
franta-hg@28
|
60 |
event_base_free(base);
|
franta-hg@28
|
61 |
|
franta-hg@28
|
62 |
printf("done\n");
|
franta-hg@28
|
63 |
return 0;
|
franta-hg@28
|
64 |
}
|
franta-hg@28
|
65 |
|
franta-hg@28
|
66 |
static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data) {
|
franta-hg@28
|
67 |
struct event_base *base = (event_base *) user_data;
|
franta-hg@28
|
68 |
struct bufferevent *bev;
|
franta-hg@28
|
69 |
|
franta-hg@28
|
70 |
bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); // zavírá spojení
|
franta-hg@28
|
71 |
//bev = bufferevent_socket_new(base, fd, 0); // nezavírá spojení
|
franta-hg@28
|
72 |
if (!bev) {
|
franta-hg@28
|
73 |
fprintf(stderr, "Error constructing bufferevent!");
|
franta-hg@28
|
74 |
event_base_loopbreak(base);
|
franta-hg@28
|
75 |
return;
|
franta-hg@28
|
76 |
}
|
franta-hg@28
|
77 |
bufferevent_setcb(bev, NULL, conn_write_cb, conn_event_cb, NULL);
|
franta-hg@28
|
78 |
bufferevent_enable(bev, EV_WRITE);
|
franta-hg@28
|
79 |
bufferevent_disable(bev, EV_READ);
|
franta-hg@28
|
80 |
|
franta-hg@28
|
81 |
printf("někdo se k nám připojil! / %p\n", bev);
|
franta-hg@28
|
82 |
|
franta-hg@28
|
83 |
bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
|
franta-hg@28
|
84 |
}
|
franta-hg@28
|
85 |
|
franta-hg@28
|
86 |
static void conn_write_cb(struct bufferevent *bev, void *user_data) {
|
franta-hg@28
|
87 |
struct evbuffer *output = bufferevent_get_output(bev);
|
franta-hg@28
|
88 |
if (evbuffer_get_length(output) == 0) {
|
franta-hg@28
|
89 |
printf("flushed answer / %p\n", bev);
|
franta-hg@28
|
90 |
bufferevent_free(bev);
|
franta-hg@28
|
91 |
}
|
franta-hg@28
|
92 |
}
|
franta-hg@28
|
93 |
|
franta-hg@28
|
94 |
static void conn_event_cb(struct bufferevent *bev, short events, void *user_data) {
|
franta-hg@28
|
95 |
if (events & BEV_EVENT_EOF) {
|
franta-hg@28
|
96 |
printf("Connection closed.\n");
|
franta-hg@28
|
97 |
} else if (events & BEV_EVENT_ERROR) {
|
franta-hg@28
|
98 |
printf("Got an error on the connection: %s\n",
|
franta-hg@28
|
99 |
strerror(errno)); /*XXX win32*/
|
franta-hg@28
|
100 |
}
|
franta-hg@28
|
101 |
|
franta-hg@28
|
102 |
// None of the other events can happen here, since we haven't enabled timeouts
|
franta-hg@28
|
103 |
bufferevent_free(bev);
|
franta-hg@28
|
104 |
}
|
franta-hg@28
|
105 |
|
franta-hg@28
|
106 |
static void signal_cb(evutil_socket_t sig, short events, void *user_data) {
|
franta-hg@28
|
107 |
struct event_base *base = (event_base *) user_data;
|
franta-hg@28
|
108 |
struct timeval delay = {2, 123};
|
franta-hg@28
|
109 |
|
franta-hg@28
|
110 |
printf("Zachycen SIGINT (Ctrl+C); ukončuji program během %ld sekund a %ld mikrosekund.\n", delay.tv_sec, delay.tv_usec);
|
franta-hg@28
|
111 |
|
franta-hg@28
|
112 |
event_base_loopexit(base, &delay);
|
franta-hg@28
|
113 |
}
|