0

Using libevent 2.1.11, reading the input evbuffer is limited to 4096 bytes. Due to EVBUFFER_MAX_READ 4096 in buffer.c

Given this information, the next read callback should be called after the first read callback with the remaining data.

Running this program, when the read callback is first called, there is only 4096 bytes which is normal given the EVBUFFER_MAX_READ 4096. Then the callback is called again but the length is only 1 bytes.

Ouptut when sending data over 4096 bytes.

Received data is: 4096 bytes
received: {string of 4096 bytes}
Received data is: 1 bytes
received:

How to retrieve all the data sent to the server.

#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <string.h>

#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>

static const int PORT = 2048;

static void conn_readcb(struct bufferevent *bev, void *arg) {
    struct evbuffer *buffer = bufferevent_get_input(bev);
    const size_t len = evbuffer_get_length(buffer);
    
    printf("Received data is: %ld bytes\n", len);

    if(len < 1)
        return;

    char *data = malloc(len);
    evbuffer_remove(buffer, data, len);

    printf("received: %s\n", data);

    free(data);
}

static void conn_writecb(struct bufferevent *bev, void *arg) {}

static void conn_eventcb(struct bufferevent *bev, short events, void *arg) {
    bufferevent_free(bev);
}

static void signal_cb(evutil_socket_t sig, short events, void *evb) {
    struct event_base *base = evb;
    struct timeval delay = {2, 0};

    event_base_loopexit(base, &delay);
}

static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
        struct sockaddr *sa, int socklen, void *evb) {
    struct event_base *base = evb;
    struct bufferevent *bev;

    bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    if(!bev) {
        fprintf(stderr, "Error constructing bufferevent");
        event_base_loopbreak(base);
        return;
    }

    bufferevent_setcb(bev, conn_readcb, conn_writecb, conn_eventcb, NULL);
    bufferevent_enable(bev, EV_WRITE|EV_READ);
}

int main(int argc, char* argv[]) {
    struct event_base *base;
    struct evconnlistener *listener;
    struct event *signal_event;

    struct sockaddr_in sin = {0};

    base = event_base_new();

    if(!base) {
        fprintf(stderr, "Could not get new event base");
        return -1;
    }

    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);

    listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
            LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1, (struct sockaddr*)&sin,
            sizeof(sin));

    if(!listener) {
        fprintf(stderr, "Could not create a listener");
        return -1;
    }

    signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);

    if(!signal_event || event_add(signal_event, NULL) < 0) {
        fprintf(stderr, "Could not create or add a singal event");
        return -1;
    }

    event_base_dispatch(base);

    evconnlistener_free(listener);
    event_free(signal_event);
    event_base_free(base);

    return 0;
}

reeves
  • 173
  • 1
  • 1
  • 11

0 Answers0