【问题标题】:Libevent: how to temporarily disable, then re-enable EV_READ? (In C)Libevent:如何暂时禁用,然后重新启用 EV_READ? (在 C 中)
【发布时间】:2012-10-19 21:53:26
【问题描述】:

我正在使用 libevent 来处理一组端口上的数据接收。我想要完成的行为是这样的:

-假设我有一组端口,1001-1004 - 读取端口上的数据,比如 1001。 - 一旦回调被击中,禁用此端口 (1001) 上的进一步读取。 - 一旦所有端口都接收到数据,将它们全部重新打开以进行读取。

现在我有一个缓冲区事件结构:

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);
}  

在我的“处理”函数中,我告诉它这样做:

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);
}

任何想法我做错了什么?当我将数据发送到随机端口时,我仍然可以发送更多、更多、更多。
蒂亚!

【问题讨论】:

    标签: c event-handling libevent


    【解决方案1】:

    看起来您只是禁用了读取套接字上的数据,但这不会阻止某人在该套接字上向您发送数据(操作系统会缓冲来自他们的大量数据,因为它假定您将有空的时候看看)。

    您无法阻止它们发送数据,但您可以停止与这些端口的新连接(通过在您想要再次接受之前不接受已阻止端口上的连接),并且您可以关闭已关闭端口上的连接(如果他们愿意)向您发送数据(这意味着您仍想在这些端口上读取数据,但如果他们向您发送任何内容,您可以 close() 他们或类似的东西。)

    【讨论】:

    • 感谢您的帮助!嗯...我明白你在说什么,但是由于我在 C 中执行此操作,因此关闭端口变得非常棘手,因为它会杀死事件侦听器并且所有这些东西都必须重新制作。我还找到了 evconnlistener_disable(),这似乎是我想要的:“这些函数暂时禁用或重新启用侦听新连接。”但在测试过程中,它实际上并没有阻止 connect() 成功。
    • 好吧,我想出了一个办法。我将把我所有的事件创建内容放入一个函数中,并在启动时调用它。然后,当我收到回调时,我会在该侦听器事件上调用evconnlistener_free()。这会释放事件并关闭套接字。然后,当我准备好重新启用所有内容时,我将再次调用我的事件创建内容。谢谢!
    猜你喜欢
    • 2011-11-14
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多