boost :: asio :: read函数挂起

时间:2016-04-17 15:35:03

标签: c++ boost-asio

如果有人能帮我解决,我无法理解boost :: asio :: read功能如何在boost asio中运行。在boost的例子中,他们在收到消息之前声明缓冲区大小是没有意义的(在读取消息之前我怎么知道要读取多少字节?)

我试过这段代码,但它只是挂起

  boost::asio::io_service io_service;

  tcp::resolver resolver(io_service);
  tcp::resolver::query query(tcp::v4(), "localhost", "3000");
  tcp::resolver::iterator iterator = resolver.resolve(query);

  tcp::socket sock(io_service);
  boost::asio::connect(sock, iterator);
  cout << "read start" << endl;
  boost::system::error_code err_code;

  // Read from client.
  boost::asio::streambuf read_buffer;
  int bytes_transferred = boost::asio::read(sock, read_buffer, err_code);
  std::cout << "Read: " << make_string(read_buffer) << std::endl;
  read_buffer.consume(bytes_transferred); // Remove data that was read.

2 个答案:

答案 0 :(得分:2)

通常,您知道要从协议定义中读取多少字节。

在相反的情况下,您必须逐个读取字节并观察错误代码,以便在连接,文件等结束时停止。

Boost.Asio中的同步方法(例如read)对于简短示例很有用,但在实际使用情况下,您应该更喜欢异步版本async_read,它允许您取消< / strong>或只是等待下一个数据块而不阻止您的程序。

答案 1 :(得分:0)

我遇到了同样的问题。似乎boost :: asio :: read应该挂起,直到连接的客户端关闭。相反,您可以像这样使用socket.read_some

using boost::asio::ip::tcp;
try {
    boost::asio::io_service io_service;

    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 9999));

    for (;;) {
        tcp::socket socket(io_service);
        acceptor.accept(socket);

        std::string message = "server received!\n";

        boost::system::error_code error_code;
        boost::asio::streambuf stream_buf;

        std::vector<char> buf(1024);
        size_t len = socket.read_some(boost::asio::buffer(buf), error_code);
        std::string received_filename(buf.begin(), buf.end());
        received_filename.resize(len);
        if (error_code) {
            std::cout << "error status: " << error_code.message() << std::endl;
        }

        boost::asio::write(socket, boost::asio::buffer(message), error_code);
        if (error_code) {
            std::cout << "error status: " << error_code.message() << std::endl;
        }
        query_database(tree, received_filename, output_folder, db_image_filenames);
    }
}
catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
}

这将通过相对较短的消息立即从客户端获取消息。希望这有帮助。