简体   繁体   中英

streambuf with boost::asio::async_write

Tell me how to use boost::asio::streambuf with boost::asio::async_write . I have a server application that connects to it one client.

For each connection I create object tcp_connection .

How do I properly create buffer for sending data if I need to send to the client several consecutive messages?

Do I need to have to synchronize calls Send() because it is they use a global buffer to be sent? Or do I need to create a separate buffer before calling async_write ?

For example, in Windows using IOCP I create my own OVERLAPPED structure containing buffer. I create a buffer before calling WSASend and delete after the operation is completed, extracting it from the OVERLAPPED Structure. Ie for each WSASend has a own buffer.

And how to do to boost::asio::async_write ?

Here I have a class 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;
};

Be really careful with async_write , you should not overlap async_write s to the same stream (see the spec http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/async_write/overload1.html ). I am not sure that you really need asynchronous writes as long as you don't need to transfer so many data and doing other things in parallel... If you really need it, then you should ensure the synchronization. You may use some locking mechanism, acquire a lock before (async) writing and unlock in the WriteHandler .

If the buffer is local to the connection and you don't access it in other threads, you don't need to lock or copy. That's no different than anywhere without using Asio.

You do need to synchronize operations on the same socket: Why do I need strand per connection when using boost::asio?

To send the whole buffer just use boost::asio::async_write .

Note: you should probably use shared_from_this() instead of this in the bind for the completion handler

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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