Libevent: как временно отключить, а затем снова включить EV_READ? (В С)
Я использую libevent для обработки данных на множестве портов. Поведение, которое я хотел бы достичь, это:
-Скажи, что у меня есть набор портов, 1001-1004 -Читайте данные о порте, скажем, 1001. -После того, как обратный вызов нажмет, отключите дальнейшее чтение на этом порту (1001). -После того как все порты получили данные, включите их все для чтения.
Прямо сейчас у меня есть структура bufferevents:
static struct bufferevent *bev[4];
Я настроил слушателей так, как они показывают в документации:
/* Listener 1 */
sin.sin_port = htons(MIXPORT + 1);
listener1 = evconnlistener_new_bind(base, accept1, NULL,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
(struct sockaddr*)&sin, sizeof(sin));
if (!listener1) { perror("Couldn't create listener1"); return 1; }
evconnlistener_set_error_cb(listener1, accept_error_cb);
static void accept1(struct evconnlistener *listener,
evutil_socket_t fd, struct sockaddr *address, int socklen,
void *ctx) {
/* A new connection was received on this port */
struct event_base *base = evconnlistener_get_base(listener);
bev[0] = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
/* Callback for when (*bufevent, data READ, data WRITTEN, event OCCURRED, *void) */
bufferevent_setcb(bev[0], read1, NULL, echo_event_cb, NULL);
/* Set bufferevent to be able to read */
bufferevent_enable(bev[0], EV_READ);
}
Затем я дал ему READ обратный вызов:
static void read1(struct bufferevent *bev, void *ctx) {
if(LOG) { logoutput("Data received on port 1"); }
struct evbuffer *input = bufferevent_get_input(bev);
size_t len = evbuffer_get_length(input);
data[0] = malloc(len);
/* Copy evbuffer data into array */
evbuffer_copyout(input, data[0], len);
/* Remove data from evbuffer after copying it out */
evbuffer_drain(input, len);
handle(0);
}
В моей функции "handle" я сказал это сделать так:
static void handle(int i)
{
/* Disable reading on port until re-enabled later */
bufferevent_disable(bev[i], EV_READ); // I thought this should do it?!
// Do other stuff...
random_function();
}
И наконец...
static void random_function(); {
/* Re-enable read on port */
bufferevent_enable(bev[src], EV_READ);
}
Есть идеи, что я делаю не так? Когда я отправляю данные на произвольный порт, я все еще могу отправлять их больше, больше и больше.
ТИА!
1 ответ
Похоже, что вы просто отключаете чтение данных в сокете, но это не помешает кому-то отправлять вам данные в этот сокет (ОС будет буферизовать из них достаточное количество данных, поскольку предполагает, что вы захотите прочитать это когда успеешь).
Вы не можете помешать им отправлять данные, но вы можете остановить новые подключения к этим портам (не принимая подключения на заблокированные порты, пока вы не захотите снова), и вы можете закрыть подключения на закрытых портах, если они отправляют вам данные (это будет означать, что вы все еще хотите читать на этих портах, но если они отправят вам что-нибудь, вы close()
их или что-то в этом роде.)