libevent2 中的分块响应
我正在尝试以这种方式在 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 *))
方法,但找不到任何有关如何使用的示例。
例如,我如何将参数传递给回调?该参数似乎与传递给请求处理程序的参数相同,这不是我想要的,因为我想创建一个保存文件描述符和我发送的文件偏移量的对象。
感谢所有帮助。
提前致谢 斯里
I am trying to do a chunked response (of large files) in libevent this way::
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);
Problem is with this I have a feeling the add_file is asynchronous so the 3rd or so evhttp_send_reply_chunk
gives me an error (or something similar):
[warn] evhttp_send_chain Closed(45): Bad file descriptor
I set MAX_READ_SIZE
to be 8
to actually test out chunked transfer encoding.
I noticed there was a evhttp_request_set_chunked_cb (struct evhttp_request *, void(*cb)(struct evhttp_request *, void *))
method I could use but could not find any examples on how to use.
For instance, how could I pass an argument to the callback? The argument seems to be the same argument that was passed to the request handler which is not what I want, because I want to create an object that holds the file descriptor and the file offset I am sending out.
Appreciate all help.
Thanks in advance
Sri
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
libevent v2 文档 没有说它是异步的,但它确实说它关闭了您的代码不考虑的文件描述符。
我相信您需要在循环内移动
int fd = open("filename", O_RDONLY);
。您还可以通过从头开始构建字符串缓冲区来测试文件代码之外的块处理。
除此之外,(最后一行应该是
fclose(fp);
你的例子看起来是正确的The libevent v2 documentation doesn't say that it's async, but it does say that it closes the file descriptor which your code doesn't account for.
I believe you need to move
int fd = open("filename", O_RDONLY);
inside your loop.you can also test the chunk handling outside of your file code by just building a string buffer from scratch.
aside from that, (and the last line which should be
fclose(fp);
your example looks correct不错 不错的伙伴。谢谢你。我刚刚意识到我想要分块传输的唯一原因是避免缓冲区读取。但由于 evbuffer_add_file 已经使用了 sendfile (如果找到的话),这并不是真正的问题。
所以我完全删除了循环并尝试了。但内容仍未发送。但至少这次我没有出现错误的文件描述符错误(你是对的 - 这是由于文件被关闭 - 文件句柄的检查证实了这一点!)。
Nice Nice mate. Thanks for that. I just realised that the only reason I wanted to chunked transfers were to avoid buffer reads. But since evbuffer_add_file already uses sendfile (if it finds it) this is not really an issue.
So I removed the loop completely and tried. But the contents are still not being sent. but atleast this time I dont have the bad file descriptor error (you are right - this was due to the file being closed - a check of file handles confirmed this!).