mrjbom
@mrjbom

Как передать сокет в хендлер или не компилируется асинхронный TCP-сервер boost::asio?

Пишу асинхронный echo TCP-сервер который должен работать с несколькими клиентами.
Я себе представляю всё так: экземпляр tcp_server ждёт подключение и когда к нему подключаются - создаёт объект класса session и передаёт туда сокет с подключением по ссылке, ну а там сокет путешествует по хендлерам и информация из него читается и записывается.
Вот решил данный код скомпилировать и потестировать с одни подключением, но вылезают ошибки.
Судя по выводу сборки, ошибки падают в bind.hpp, полагаю ему не нравится то, что там сокет передаётся по ссылке.
Как исправить?

#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;
}
  • Вопрос задан
  • 111 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы