Thread: Boost::asio unithread server-client problem.

  1. #1
    Registered User
    Join Date
    Aug 2016
    Posts
    1

    Boost::asio unithread server-client problem.

    I try to write an async message to the server from my client code, the write handler gets called with the correct bytes sent; however, the server receives 0 bytes.

    Cliente output:
    Code:
    You are connected 
    You received the following message from the server: Sat Aug 20 17:42:01 2016 
    Sending...
    Server output:
    Code:
    Server is online! 
    127.0.0.1:51973 connected! 
    Client has received the messaged. 
    You received the following message from the server:
    server source: #include <ctime> #include <iostream> #include <string> #include <boost/bind.h - Pastebin.com
    Code:
    #include <ctime>
    #include <iostream>
    #include <string>
    #include <boost/bind.hpp>
    #include <boost/shared_ptr.hpp>
    #include <boost/enable_shared_from_this.hpp>
    #include <boost/asio.hpp>
    #include <boost/array.hpp>
    
    using boost::asio::ip::tcp;
    
    std::string make_daytime_string()
    {
        using namespace std; // For time_t, time and ctime;
        time_t now = time(0);
        return ctime(&now);
    }
    
    
    class tcp_connection: public boost::enable_shared_from_this<tcp_connection>
    {
    public:
        typedef boost::shared_ptr<tcp_connection> pointer;
        
        static pointer create(boost::asio::io_service& io_service)
        {
            return pointer(new tcp_connection(io_service));
        }
        
        tcp::socket& socket()
        {
            return socket_;
        }
        
        // Call boost::asio::async_write() to serve the data to the client.
        // We are using boost::asio::async_write(),
        // rather than ip::tcp::socket::async_write_some(),
        // to ensure that the entire block of data is sent.
        
        void start()
        {
            // The data to be sent is stored in the class member m_message
            // as we need to keep the data valid
            // until the asynchronous operation is complete.
            
            m_message = make_daytime_string();
            
            // When initiating the asynchronous operation,
            // and if using boost::bind(),
            // we must specify only the arguments
            // that match the handler's parameter list.
            // In this code, both of the argument placeholders
            // (boost::asio::placeholders::error
            // and boost::asio::placeholders::bytes_transferred)
            // could potentially have been removed,
            // since they are not being used in handle_write().
            
            std::cout << socket_.remote_endpoint().address().to_string() << ":" << socket_.remote_endpoint().port() << " connected!" << std::endl;
            
            boost::asio::async_write(socket_, boost::asio::buffer(m_message),
                                     boost::bind(&tcp_connection::handle_write, shared_from_this()));
            
            boost::asio::async_read(socket_, boost::asio::buffer(_buffer), boost::bind(&tcp_connection::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
        }
    
        
    private:
        tcp_connection(boost::asio::io_service& io_service)
        : socket_(io_service)
        {
        }
        // handle_write() is responsible for any further actions
        // for this client connection.
        
        void handle_write() // call back.. when it finishes sending, we come here
        {
            std::cout << "Client has received the messaged. " << std::endl;
        }
        
        void handle_receive(const boost::system::error_code& ErrorCode, std::size_t bytes_transferred)
        {
            std::cout << "You received the following message from the server:" << std::endl;
            std::cout.write(_buffer.data(), bytes_transferred);
            
        }
        
        tcp::socket socket_;
        std::string m_message;
        boost::array<char, 126> _buffer;
    };
    
    class tcp_server
    {
    public:
        tcp_server(boost::asio::io_service& io_service) : acceptor_(io_service, tcp::endpoint(tcp::v4(), 7171))
        {
            // start_accept() creates a socket and
            // initiates an asynchronous accept operation
            // to wait for a new connection.
            start_accept();
        }
        
    private:
        void start_accept()
        {
            // creates a socket
            tcp_connection::pointer new_connection = tcp_connection::create(acceptor_.get_io_service());
            
            // initiates an asynchronous accept operation
            // to wait for a new connection.
            acceptor_.async_accept(new_connection->socket(),
                                   boost::bind(&tcp_server::handle_accept, this, new_connection,
                                               boost::asio::placeholders::error));
        }
        
        // handle_accept() is called when the asynchronous accept operation
        // initiated by start_accept() finishes. It services the client request
        void handle_accept(tcp_connection::pointer new_connection,
                           const boost::system::error_code& error)
        {
            if (!error)
            {
                new_connection->start();
            }
            
            // Call start_accept() to initiate the next accept operation.
            start_accept();
        }
        
        tcp::acceptor acceptor_;
    };
    
    int main()
    {
        std::cout << "Server is online!" << std::endl;
        try
        {
            boost::asio::io_service io_service;
            
            tcp_server server(io_service);
            
            io_service.run();
            
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
        
        return 0;
    }
    client source: #include <iostream> #include <boost/array.hpp> #include <boost/bind.hpp> #inc - Pastebin.com
    Code:
    #include <iostream>
    #include <boost/array.hpp>
    #include <boost/bind.hpp>
    #include <boost/asio.hpp>
    
    using boost::asio::ip::tcp;
    
    std::string make_daytime_string()
    {
        using namespace std; // For time_t, time and ctime;
        time_t now = time(0);
        return ctime(&now);
    }
    
    class Connection
    {
    public:
        Connection(boost::asio::io_service& io) : _socket(io){}
        
        void connect(tcp::resolver::iterator& point)
        {
            boost::asio::async_connect(_socket, point, boost::bind(&Connection::onConnected, this, boost::asio::placeholders::error));
        }
        
        void onConnected(const boost::system::error_code& ErrorCode)
        {
            std::cout << "You are connected" << std::endl;
            
            // receive first message on onReceive
            boost::asio::async_read(_socket, boost::asio::buffer(_buffer), boost::bind(&Connection::onReceive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
        }
        
        void onSend(const boost::system::error_code& ErrorCode, std::size_t bytes_transferred)
        {
            std::cout << "Sending..." << std::endl;
        }
        
        void onReceive(const boost::system::error_code& ErrorCode, std::size_t bytes_transferred)
        {
            std::cout << "You received the following message from the server:" << std::endl;
            std::cout.write(_buffer.data(), bytes_transferred);
            
            // send first message on onSend
            m_message = make_daytime_string();
            boost::asio::async_write(_socket, boost::asio::buffer(m_message), boost::bind(&Connection::onSend, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
        }
        
        tcp::socket& getSocket()
        {
            return _socket;
        }
    private:
        tcp::socket _socket;
        boost::array<char, 126> _buffer;
        std::string m_message;
    };
    
    int main()
    {
        try
        {
            boost::asio::io_service io_service;
            
            tcp::resolver resolver(io_service);
    
            tcp::resolver::query query("127.0.0.1", "7171");
            
            tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
            
            Connection conn(io_service);
            conn.connect(endpoint_iterator);
            
            io_service.run();
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
        
        return 0;
    }
    Last edited by Salem; 08-21-2016 at 12:52 AM. Reason: Inlined pastebin lazyness

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Boost.Asio's io_service and event handling
    By Chris87 in forum C++ Programming
    Replies: 12
    Last Post: 02-06-2016, 02:32 PM
  2. Converting From Boost::Asio::streambuf to a string
    By EverydayDiesel in forum C++ Programming
    Replies: 2
    Last Post: 01-07-2016, 11:26 AM
  3. Boost Asio and asynchronous I/O
    By Elysia in forum C++ Programming
    Replies: 9
    Last Post: 06-19-2011, 07:51 PM
  4. Boost ASIO
    By PetrolMan in forum C++ Programming
    Replies: 0
    Last Post: 04-10-2009, 03:24 PM
  5. Client/server problem; server either stops receiving data or client stops sending
    By robot-ic in forum Networking/Device Communication
    Replies: 10
    Last Post: 02-16-2009, 11:45 AM

Tags for this Thread