javascript - Boost::asio async_read 简单文件上传
问题描述
我正在尝试使用 boost::asio 和 ajax 创建一个简单的文件上传。不知何故,即使我的缓冲区大小为 500MB,bytes_transferred 也达到了最大值 21845(或类似的值)。对于文本文件 std::cout 会显示一些内容,但对于二进制文件,它会在标题之后立即切断(仍然传输 21845 个字节)。
我尝试使用不同的方法,如 async_read_some 和 async_read_until 但它没有改变任何东西。还尝试了使用 keep-alive 和更改套接字缓冲区大小的 socket.set_option() 。
class tcp_connection
{
public:
void start() {
boost::asio::async_read(socket, boost::asio::buffer(buf), boost::asio::transfer_at_least(1), boost::bind(&tcp_connection::handler, error, bytes_transferred));
}
private:
boost::array<unsigned char, 500000000> buf;
void handler(error, bytes) {
std::cout << buf.data() << std::endl;
boost::asio::async_write(socket, response_buffer, boost::bind(&tcp_connection, handler));
}
}
请查看https://pastebin.com/dPvVGsjU以获取完整的最小可复制示例
尽管我忽略了 eof 错误,但我没有收到错误消息。
解决方案
为什么您认为在一次读取操作期间将读取整个数据?您的完成条件是transfer_at_least(1)
,因此读取操作可以读取 1、10、100 或 N 个字节并返回。您应该读取数据,直到收到整个内容。因为您不知道输入数据的长度,所以您继续阅读直到eof
发生。
所以传入的处理程序的逻辑async_read
应该是:
void send_response2(const boost::system::error_code& err, const size_t& bytes)
{
if (err == boost::asio::error::eof)
{
// analyze your buf2 here if it is what you wanted to read
// here you can start sending data
}
else if (err)
{ /* problem */ }
else
{
// call again async_read with send_response like
boost::asio::async_read(socket, boost::asio::dynamic_buffer(buf2), boost::asio::transfer_at_least(1), boost::bind(&tcp_connection::send_response2, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
buffer::array
您可以使用动态缓冲区,而不是固定大小的缓冲区。然后通过添加新的读取字节来扩展您的缓冲区。
std::string buf2; // as data member
// then pass buffer by
boost::asio::dynamic_buffer(buf2)
推荐阅读
- go - 当函数返回运动员时,为什么 Go 是“运动员声明而不使用”?
- reactjs - ReactNative 项目性能
- php - 修复 php 代码行中的问题 $sql = SELECT item FROM table WHERE user = $user
- php - Web 服务器上的 PHP while 循环行为不同
- javascript - 如何修复javascript对象中的循环引用?
- c# - 使用 XElement 作为 XElement 数组并访问它们
- java - 卡夫卡代理字节输出尖峰发送,而卡夫卡字节不断进来
- c# - IQueryable 和 AsEnumerable():延迟执行与立即执行
- swift - 如何从 Swift 5 中的另一个类获取数组
- node.js - 在 Kubernetes 集群中的所有 pod 之间共享 express.js 应用程序的公共目录