libevent: čtení ze soketu: první část
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sat, 19 Nov 2016 18:27:08 +0100
changeset 30efa6fc19b006
parent 29 9c0f52aa4772
child 31 baa90e4359c8
libevent: čtení ze soketu: první část
c++/domain-socket-bridge/domain-socket-bridge.c
     1.1 --- a/c++/domain-socket-bridge/domain-socket-bridge.c	Fri Nov 18 23:07:02 2016 +0100
     1.2 +++ b/c++/domain-socket-bridge/domain-socket-bridge.c	Sat Nov 19 18:27:08 2016 +0100
     1.3 @@ -2,6 +2,7 @@
     1.4  #include <errno.h>
     1.5  #include <stdio.h>
     1.6  #include <signal.h>
     1.7 +#include <stdlib.h>
     1.8  
     1.9  #include <event2/bufferevent.h>
    1.10  #include <event2/buffer.h>
    1.11 @@ -11,12 +12,14 @@
    1.12  #include <sys/un.h>
    1.13  #include <unistd.h>
    1.14  
    1.15 +#define MAX_LINE 16384
    1.16 +
    1.17  static const char MESSAGE[] = "Hello, World!\n";
    1.18  
    1.19  static const char PATH[] = "./roura";
    1.20  
    1.21 -static void listener_cb(struct evconnlistener *, evutil_socket_t,
    1.22 -		struct sockaddr *, int socklen, void *);
    1.23 +static void listener_cb(struct evconnlistener *, evutil_socket_t, struct sockaddr *, int socklen, void *);
    1.24 +static void conn_read_cb(struct bufferevent *, void *);
    1.25  static void conn_write_cb(struct bufferevent *, void *);
    1.26  static void conn_event_cb(struct bufferevent *, short, void *);
    1.27  static void signal_cb(evutil_socket_t, short, void *);
    1.28 @@ -60,7 +63,7 @@
    1.29  	evconnlistener_free(listener);
    1.30  	event_free(signal_event);
    1.31  	event_base_free(base);
    1.32 -	
    1.33 +
    1.34  	// smažeme soket na disku / soubor -- jinak by program příště spadl na evconnlistener_new_bind()
    1.35  	unlink(PATH);
    1.36  
    1.37 @@ -72,22 +75,45 @@
    1.38  	struct event_base *base = (event_base *) user_data;
    1.39  	struct bufferevent *bev;
    1.40  
    1.41 -	bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); // zavírá spojení
    1.42 -	//bev = bufferevent_socket_new(base, fd, 0); // nezavírá spojení
    1.43 +	//bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); // zavírá spojení
    1.44 +	bev = bufferevent_socket_new(base, fd, 0); // nezavírá spojení
    1.45  	if (!bev) {
    1.46  		fprintf(stderr, "Error constructing bufferevent!");
    1.47  		event_base_loopbreak(base);
    1.48  		return;
    1.49  	}
    1.50 -	bufferevent_setcb(bev, NULL, conn_write_cb, conn_event_cb, NULL);
    1.51 -	bufferevent_enable(bev, EV_WRITE);
    1.52 -	bufferevent_disable(bev, EV_READ);
    1.53 +	bufferevent_setcb(bev, conn_read_cb, conn_write_cb, conn_event_cb, NULL);
    1.54 +	bufferevent_setwatermark(bev, EV_READ, 0, MAX_LINE);
    1.55 +	bufferevent_enable(bev, EV_READ | EV_WRITE);
    1.56  
    1.57  	printf("někdo se k nám připojil! / %p\n", bev);
    1.58  
    1.59  	bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
    1.60  }
    1.61  
    1.62 +static void conn_read_cb(struct bufferevent *bev, void *user_data) {
    1.63 +	/* This callback is invoked when there is data to read on bev. */
    1.64 +	struct evbuffer *input = bufferevent_get_input(bev);
    1.65 +	struct evbuffer *output = bufferevent_get_output(bev);
    1.66 +	struct event_base *base = (event_base *) user_data;
    1.67 +
    1.68 +	size_t len = evbuffer_get_length(input);
    1.69 +	char *data;
    1.70 +	data = (char*) malloc(len);
    1.71 +	evbuffer_copyout(input, data, len);
    1.72 +
    1.73 +	printf("we got some data: %s / %d\n", data, memcmp(data, "exit", len));
    1.74 +
    1.75 +	if (memcmp(data, "exit\n", len) == 0) {
    1.76 +		struct timeval delay = {2, 123};
    1.77 +		event_base_loopexit(base, &delay);
    1.78 +	}
    1.79 +
    1.80 +	/* Copy all the data from the input buffer to the output buffer. */
    1.81 +	evbuffer_add_buffer(output, input);
    1.82 +	free(data);
    1.83 +}
    1.84 +
    1.85  static void conn_write_cb(struct bufferevent *bev, void *user_data) {
    1.86  	struct evbuffer *output = bufferevent_get_output(bev);
    1.87  	if (evbuffer_get_length(output) == 0) {
    1.88 @@ -100,8 +126,7 @@
    1.89  	if (events & BEV_EVENT_EOF) {
    1.90  		printf("Connection closed.\n");
    1.91  	} else if (events & BEV_EVENT_ERROR) {
    1.92 -		printf("Got an error on the connection: %s\n",
    1.93 -				strerror(errno));
    1.94 +		printf("Got an error on the connection: %s\n", strerror(errno));
    1.95  	}
    1.96  
    1.97  	// None of the other events can happen here, since we haven't enabled timeouts