0

我正在尝试以这种方式在 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给了我一个错误(或类似的东西):

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

MAX_READ_SIZE打算8实际测试分块传输编码。

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

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

感谢所有帮助。

在此先感谢

4

2 回答 2

0

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

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

于 2010-03-24T19:03:06.663 回答
0

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

我相信你需要int fd = open("filename", O_RDONLY);进入你的循环。

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

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

于 2010-03-21T22:49:24.200 回答