G
G
German2019-02-24 13:05:49
C++ / C#
German, 2019-02-24 13:05:49

How to pass socket to handler or boost::asio asynchronous TCP server not compiling?

I am writing an asynchronous echo TCP server that should work with multiple clients.
I imagine everything like this: an instance of tcp_server is waiting for a connection, and when it is connected to, it creates an object of the session class and passes a socket there with a connection by reference, well, there the socket travels through handlers and information is read and written from it.
So I decided to compile and test this code with one connection, but errors come out.
Judging by the output of the assembly, errors fall in bind.hpp, I suppose he does not like the fact that the socket is passed by reference there.
How to fix?

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <clocale>
#include <vector>
#include <conio.h>

using namespace boost::asio;
using namespace std;

class session
{
private:
    enum { message_lenght = 1024 };
    char buff[message_lenght];
public:
    session(ip::tcp::socket& socket)
    {
        do_read(socket);
    }
private:
    void do_read(ip::tcp::socket& socket)
    {
        socket.async_read_some(
            buffer(buff),
            boost::bind(
                &session::read_handler,
                this,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred,
                &socket
            )
        );
    }
    void read_handler(const boost::system::error_code& error, size_t bytes_transferred, ip::tcp::socket& socket)
    {
        if (!error)
        {
            socket.async_write_some(
                buffer(buff),
                boost::bind(
                    &session::write_handler,
                    this,
                    boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred,
                    &socket
                )
            );
        }
        else
        {
            cout << "Error read from socket\n";
            cout << error.message() << endl;
            _getch();
        }
    }
    void write_handler(const boost::system::error_code& error, size_t bytes_transferred, ip::tcp::socket& socket)
    {
        if (!error)
        {
            do_read(socket);
        }
        else
        {
            cout << "Error write in socket\n";
            cout << error.message() << endl;
            _getch();
        }
    }
};

class tcp_server
{
private:
    ip::tcp::socket socket;
    ip::tcp::acceptor acceptor;
    int clientCount = 0;
    int port;
public:
    tcp_server(io_service& service, int port) : socket(service), acceptor(
        service,
        ip::tcp::endpoint(ip::tcp::v4(), port))
    {
        this->port = port;
        do_accept();
    }
private:
    void do_accept()
    {
        acceptor.async_accept(
            boost::bind(
                &tcp_server::accept_handler,
                this,
                boost::asio::placeholders::error
            )
        );
    }
    void accept_handler(const boost::system::error_code& error)
    {
        if (!error)
        {
            session* new_session = new session{ socket };
        }
        else
        {
            cout << "Acceptor error\n";
            cout << error.message() << endl;
            _getch();
        }
    }
};

int main(int argc, char *argv[])
{
    try
    {
        setlocale(LC_ALL, "Rus");
        io_service service;
        tcp_server* server = new tcp_server{ service, 5000 };
        service.run();
    }
    catch (exception& ex)
    {
        cout << "Exception: " << ex.what();
    }
    return 0;
}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question