#c #multithreading #boost #server
#c #многопоточность #повышение #сервер
Вопрос:
Мне нужно создать проект синхронного TCP-сервера, и я начал с примера библиотеки boost, основная проблема в том, что я хотел бы создать многопоточный сервер, на самом деле с примером кода сервер может принимать только одно соединение за раз. Я внимательно прочитал документацию, но я не понимаю, какая функция вызывается, когда новый запрос был отправлен на сервер. Концептуально я понимаю, как работать, я запускаю новый поток при поступлении нового запроса на подключение, но, прочитав код, я не знаю, с чего начать.
#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>
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(amp;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_serviceamp; io_service)
{
return pointer(new tcp_connection(io_service));
}
tcp::socketamp; socket()
{
return socket_;
}
void start()
{
message_ = make_daytime_string();
boost::asio::async_write(socket_, boost::asio::buffer(message_),
boost::bind(amp;tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
tcp_connection(boost::asio::io_serviceamp; io_service)
: socket_(io_service)
{
}
void handle_write(const boost::system::error_codeamp; /*error*/,
size_t /*bytes_transferred*/)
{
}
tcp::socket socket_;
std::string message_;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_serviceamp; io_service)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))
{
start_accept();
}
private:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.get_io_service());
acceptor_.async_accept(new_connection->socket(),
boost::bind(amp;tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_codeamp; error)
{
if (!error)
{
new_connection->start();
}
start_accept();
}
tcp::acceptor acceptor_;
};
int main()
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service);
io_service.run();
}
catch (std::exceptionamp; e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
Комментарии:
1. В этом примере сервер отправляет только данные. Вы должны сделать что-то подобное для чтения. Асинхронный код может выглядеть сложнее (это сделано в этом примере), но это намного проще, чем использование синхронного API с потоками.
2. На самом деле серверу просто нужно отправлять данные, клиенты должны только читать, поэтому пример идеально подходит для того, что мне нужно сделать. Основная проблема заключается в том, что вместо простого datetime должна быть отправлена длинная текстовая информация, и я должен принимать больше запросов на подключение одновременно
3. Итак
tcp_connection::start
, записывается первое сообщение, а следующее сообщение должно быть отправлено изtcp_connection::handle_write
.4. Кроме того, это означает, что tcp_connection::handle_write должен быть без тела
5. Если после отправки вы больше ничего не хотите делать, вы можете просто оставить это пустое yes. После завершения этой функции она автоматически закроет сокет tcp-соединения и удалит
tcp_connection
экземпляр