简体   繁体   English

Boost :: asio async_read简单文件上传

[英]Boost::asio async_read simple file upload

I'm trying to create a simple file upload using boost::asio and ajax. 我正在尝试使用boost :: asio和ajax创建一个简单的文件上传。 Somehow the bytes_transferred reaches a maximum at 21845 (or something like that) even though my buffer size is 500MB. 即使我的缓冲区大小为500MB,bytes_transferred也会以某种方式达到最大值21845(或类似值)。 With text files std::cout displays something but with binary files it cuts off right after the header (still 21845 bytes are transferred). 使用文本文件std :: cout会显示某些内容,但是使用二进制文件时,它将在标头之后立即切断(仍传输21845个字节)。

I tried using different methods like async_read_some and async_read_until but it didn't change anything. 我尝试使用不同的方法,例如async_read_some和async_read_until,但没有任何改变。 Also tried socket.set_option() with keep-alive and changing socket buffer size. 还尝试了使用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));
}
}

Please look at https://pastebin.com/dPvVGsjU for the full minimal-reproductible example 请查看https://pastebin.com/dPvVGsjU ,了解完整的最小可复制示例

I don't receive error messages, although I am ignoring eof errors. 尽管我忽略了eof错误,但我没有收到错误消息。

Why do you suppose that the whole data will be read during one read operation ? 您为什么会在一次读取操作中读取全部数据? Your completion condition is transfer_at_least(1) , so read operation can read 1, 10, 100 or N bytes and return. 您的完成条件是transfer_at_least(1) ,因此读取操作可以读取1、10、100或N个字节并返回。 You should read data until the whole content is received. 您应该读取数据,直到收到全部内容。 Because you don't know the length of input data, you continue reading until eof occures. 由于您不知道输入数据的长度,因此请继续阅读直到出现eof为止。

So logic of handler passed into async_read should be: 因此,传递给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));
    }
}   

Instead of buffer::array as buffer with fixed size, you can use dynamic buffer . 可以使用dynamic buffer来代替buffer::array作为具有固定大小的缓冲区 Then your buffer will be extended, by adding new read bytes. 然后,通过添加新的读取字节来扩展缓冲区。

std::string buf2; // as data member
// then pass buffer by
boost::asio::dynamic_buffer(buf2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM