libevent2 中的分块响应

Posted

技术标签:

【中文标题】libevent2 中的分块响应【英文标题】:Chunked responses in libevent2 【发布时间】:2010-03-18 07:15:02 【问题描述】:

我正在尝试以这种方式在 libevent 中进行分块响应(大文件)::

evhttp_send_reply_start(request, HTTP_OK, "OK");

int fd = open("filename", O_RDONLY);
size_t fileSize = <get_file_size>;
struct evbuffer *databuff = NULL;
for (off_t offset = 0;offset < fileSize;)

    databuff = evbuffer_new();

    size_t bytesLeft = fileSize - offset;
    size_t bytesToRead = bytesLeft > MAX_READ_SIZE ? MAX_READ_SIZE : bytesLeft;

    evbuffer_add_file(databuff, fd, offset, bytesToRead);
    offset += bytesToRead;

    evhttp_send_reply_chunk(request, databuff); // send it
    evbuffer_free(databuff);                    // destroy it


evhttp_send_reply_end(request);

fclose(fptr);

问题在于我觉得 add_file 是异步的,所以第三个左右 evhttp_send_reply_chunk 给了我一个错误(或类似的东西):

[warn] evhttp_send_chain Closed(45): 错误的文件描述符

我将MAX_READ_SIZE 设置为8 以实际测试分块传输编码。

我注意到有一个 evhttp_request_set_chunked_cb (struct evhttp_request *, void(*cb)(struct evhttp_request *, void *)) 方法我可以使用,但找不到任何有关如何使用的示例。

例如,我如何将参数传递给回调?该参数似乎与传递给请求处理程序的参数相同,这不是我想要的,因为我想创建一个包含文件描述符和我发送出去的文件偏移量的对象。

感谢所有帮助。

提前致谢 斯里

【问题讨论】:

【参考方案1】:

libevent v2 documentation 并没有说它是异步的,但它确实说它关闭了你的代码没有考虑的文件描述符。

我相信您需要将 int fd = open("filename", O_RDONLY); 移动到循环中。

您还可以通过从头开始构建字符串缓冲区来测试文件代码之外的块处理。

除此之外,(最后一行应该是 fclose(fp); 你的例子看起来是正确的

【讨论】:

【参考方案2】:

不错不错的伙伴。感谢那。我刚刚意识到,我想要分块传输的唯一原因是避免缓冲区读取。但是由于 evbuffer_add_file 已经使用了 sendfile (如果找到的话),这并不是一个真正的问题。

所以我完全删除了循环并尝试了。但是内容仍然没有发送。但至少这次我没有错误的文件描述符错误(你是对的 - 这是由于文件被关闭 - 检查文件句柄证实了这一点!)。

【讨论】:

Sri,请使用此注释更新您的问题并接受答案(或在问题中添加 cmets),尽量不要在其他答案中添加说明

以上是关于libevent2 中的分块响应的主要内容,如果未能解决你的问题,请参考以下文章

libevent2 http 未检测到客户端网络中断

使用 libevent2 处理文件 I/O 的问题

如何在 Windows 上编译 libevent2?

Libevent 2.0.22 项目编译问题(OSX)

解决“libevent-pthreads-2.1 cannot open shared object file“问题

Libevent HTTP 服务器和压缩?