streambuf with boost :: asio :: async_write

时间:2015-02-18 09:06:20

标签: c++ boost-asio streambuf

告诉我如何将boost::asio::streambufboost::asio::async_write一起使用。 我有一个服务器应用程序连接到它一个客户端。

对于每个连接,我创建了对象tcp_connection

如果我需要向客户端发送几条连续的消息,如何正确创建用于发送数据的缓冲区?

我是否需要同步调用Send(),因为它们是否使用全局缓冲区进行发送?或者在调用async_write之前是否需要创建单独的缓冲区?

例如,在使用IOCP的Windows中,我创建了自己的包含缓冲区的OVERLAPPED结构。 我在调用WSASend之前创建一个缓冲区,并在操作完成后删除, 从OVERLAPPED结构中提取它。即每个WSASend都有自己的缓冲区。

如何处理boost::asio::async_write

我有一个班级tcp_connection

#include <boost/asio.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/bind.hpp>
#include <iostream>

class tcp_connection
    // Using shared_ptr and enable_shared_from_this Because we want to keep the
    // tcp_connection object alive As long as there is an operation that refers to
    // it.
    : public boost::enable_shared_from_this<tcp_connection> {

    tcp_connection(boost::asio::io_service& io) : m_socket(io) {}

    void send(std::string data) {
        {
            std::ostream stream(&send_buffer);
            stream << data;
        }

        std::cout << "Send Data   =" << data                     << std::endl;
        std::cout << "Send Buffer =" << make_string(send_buffer) << std::endl;

        boost::asio::async_write(m_socket, send_buffer,
                                 boost::bind(&tcp_connection::handle_send, this, 
                                     boost::asio::placeholders::error,
                                     boost::asio::placeholders::bytes_transferred));
    }
    void handle_send(const boost::system::error_code &error, size_t);

  private:
    static std::string make_string(boost::asio::streambuf const&) { return "implemented elsewhere"; }
    boost::asio::ip::tcp::socket m_socket;
    boost::asio::streambuf send_buffer;
};

2 个答案:

答案 0 :(得分:1)

async_write非常小心,您不应将async_write重叠到相同的流中(请参阅规范http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/async_write/overload1.html)。我不确定你是否真的需要异步写入,只要你不需要传输这么多数据并同时做其他事情......如果你真的需要它,那么你应该确保同步。您可以使用某种锁定机制,在WriteHandler之前(异步)写入和解锁时获取锁定。

答案 1 :(得分:1)

如果缓冲区是连接的本地缓冲区,并且您无法在其他线程中访问它,则无需锁定或复制。这与没有使用Asio的任何地方没有什么不同。

需要在同一个套接字上同步操作:Why do I need strand per connection when using boost::asio?

要发送整个缓冲区,只需使用boost::asio::async_write

注意:您应该在绑定中使用shared_from_this()而不是this来完成处理程序