Пишу асинхронный 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;
}