libevent2 http服务器如何检测客户端关闭

时间:2013-09-11 14:27:58

标签: http libevent

我编写了一个处理长轮询的简单Web服务器,这意味着服务器不会向客户端发送完整的HTTP响应(Web浏览器,curl等),但只发送HTTP头并挂起连接

我使用命令行curl向服务器发出请求,它会很好地打印出HTTP响应标头,并且curl会按预期挂起。然后我按CTRL + C来终止卷曲过程。但服务器永远不会知道这个接近(永远不会调用on_disconnect())。

部分代码:

void request_handler(struct evhttp_request *req, void *arg){
    // only send response headers, and one piece of chunked data
    evhttp_send_reply_start(req, HTTP_OK, "OK");
    evbuffer_add_printf(buf, "...\n");
    evhttp_send_reply_chunk(req, buf);
    // register connection close callback
    evhttp_connection_set_closecb(req->evcon, on_disconnect, sub);
}

void on_disconnect(struct evhttp_connection *evcon, void *arg){
    printf("disconnected\n");
}

evhttp_set_gencb(http, request_handler, NULL);

我的问题是,如何检测这种客户端关闭(收到TCP FIN)?

github

的错误

1 个答案:

答案 0 :(得分:2)

我认为这是libevent中的一个错误。

我对libevent 2.0.21有类似的问题,这就是我的情况:当libevent的http.c中的evhttp_read_header()完成从客户端读取HTTP头时,它通过调用bufferevent_disable来禁用任何将来的读事件(...,EV_READ)。但是,需要为底层bufferevent启用读取事件以报告EOF。这就是为什么当客户端关闭连接时,bufferevent永远不会告诉libevent的HTTP代码。

我通过在evhttp_read_header()中删除对bufferevent_disable()的调用来解决我的问题。我使用“连接:关闭”,只有GET请求,所以客户端永远不会在标题之后发送任何数据,这个解决方案似乎适用于这个非常具体和简单的用例。但是,我不确定这是否会破坏其他用例,尤其是当您使用持久连接或“Expect:100-continue”之类的事情时。

你可能想把它带到libevent邮件列表。

相关问题