如何在单独的线程中启动 Boost echo 服务器
How to start Boost echo server in a separate thread
我在单独的线程运行中使用提升版本提升 1_64_0 到 运行 Tcp 服务器
这是服务器代码。
https://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp
在主循环中,我可以像这样生成一个新线程。
int main()
{
// Run the boost echo server as a different thread
boost::asio::io_service io_service;
server server1(io_service, 1980);
boost::thread t(boost::bind(&io_service::run, &io_service));
// when about to close the program
io_service.stop(); // stop the server
t.join();
}
现在我已经将 boost 版本更改为 boost_1_73_0 并且我正在使用此示例创建服务器
如何创建新线程?
创建新线程的现有代码出错。
io_service: :: 左边必须是 class/struct/union
运行 : 未声明的标识符
在 &io_service::run
中,io_service
不是类型,而是该名称的局部变量。
io_context.run();
需要像
std::thread t([&] { io_context.run(); });
// ...
t.join();
或者如果你坚持:
std::thread t(boost::bind(&boost::asio::io_context::run, &io_context));
我会使用 thread_pool 来简化所有的复杂性¹:
boost::asio::thread_pool io(1);
server s(io.get_executor(), std::atoi(argv[1]));
// ...
io.join();
需要对 class 界面进行简单的编辑(参见 )
//
// async_tcp_echo_server.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
using boost::asio::ip::tcp;
class session : public std::enable_shared_from_this<session> {
public:
session(tcp::socket socket) : socket_(std::move(socket)) {}
void start() { do_read(); }
private:
void do_read() {
auto self(shared_from_this());
socket_.async_read_some(
boost::asio::buffer(data_, max_length),
[this, self](boost::system::error_code ec, std::size_t length) {
if (!ec) {
do_write(length);
}
});
}
void do_write(std::size_t length) {
auto self(shared_from_this());
boost::asio::async_write(
socket_, boost::asio::buffer(data_, length),
[this, self](boost::system::error_code ec, std::size_t /*length*/) {
if (!ec) {
do_read();
}
});
}
tcp::socket socket_;
enum { max_length = 1024 };
char data_[max_length];
};
class server {
public:
template <typename Executor>
server(Executor ex, short port)
: acceptor_(ex, tcp::endpoint(tcp::v4(), port)) {
do_accept();
}
private:
void do_accept() {
acceptor_.async_accept(
[this](boost::system::error_code ec, tcp::socket socket) {
if (!ec) {
std::make_shared<session>(std::move(socket))->start();
}
do_accept();
});
}
tcp::acceptor acceptor_;
};
int main(int argc, char* argv[]) {
try {
if (argc != 2) {
std::cerr << "Usage: async_tcp_echo_server <port>\n";
return 1;
}
boost::asio::thread_pool io(1);
server s(io.get_executor(), std::atoi(argv[1]));
// ...
io.join();
} catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n";
}
}
¹ 参见示例Should the exception thrown by boost::asio::io_service::run() be caught?
我在单独的线程运行中使用提升版本提升 1_64_0 到 运行 Tcp 服务器
这是服务器代码。
https://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp
在主循环中,我可以像这样生成一个新线程。
int main()
{
// Run the boost echo server as a different thread
boost::asio::io_service io_service;
server server1(io_service, 1980);
boost::thread t(boost::bind(&io_service::run, &io_service));
// when about to close the program
io_service.stop(); // stop the server
t.join();
}
现在我已经将 boost 版本更改为 boost_1_73_0 并且我正在使用此示例创建服务器
如何创建新线程?
创建新线程的现有代码出错。
io_service: :: 左边必须是 class/struct/union
运行 : 未声明的标识符
在 &io_service::run
中,io_service
不是类型,而是该名称的局部变量。
io_context.run();
需要像
std::thread t([&] { io_context.run(); });
// ...
t.join();
或者如果你坚持:
std::thread t(boost::bind(&boost::asio::io_context::run, &io_context));
我会使用 thread_pool 来简化所有的复杂性¹:
boost::asio::thread_pool io(1);
server s(io.get_executor(), std::atoi(argv[1]));
// ...
io.join();
需要对 class 界面进行简单的编辑(参见
//
// async_tcp_echo_server.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
using boost::asio::ip::tcp;
class session : public std::enable_shared_from_this<session> {
public:
session(tcp::socket socket) : socket_(std::move(socket)) {}
void start() { do_read(); }
private:
void do_read() {
auto self(shared_from_this());
socket_.async_read_some(
boost::asio::buffer(data_, max_length),
[this, self](boost::system::error_code ec, std::size_t length) {
if (!ec) {
do_write(length);
}
});
}
void do_write(std::size_t length) {
auto self(shared_from_this());
boost::asio::async_write(
socket_, boost::asio::buffer(data_, length),
[this, self](boost::system::error_code ec, std::size_t /*length*/) {
if (!ec) {
do_read();
}
});
}
tcp::socket socket_;
enum { max_length = 1024 };
char data_[max_length];
};
class server {
public:
template <typename Executor>
server(Executor ex, short port)
: acceptor_(ex, tcp::endpoint(tcp::v4(), port)) {
do_accept();
}
private:
void do_accept() {
acceptor_.async_accept(
[this](boost::system::error_code ec, tcp::socket socket) {
if (!ec) {
std::make_shared<session>(std::move(socket))->start();
}
do_accept();
});
}
tcp::acceptor acceptor_;
};
int main(int argc, char* argv[]) {
try {
if (argc != 2) {
std::cerr << "Usage: async_tcp_echo_server <port>\n";
return 1;
}
boost::asio::thread_pool io(1);
server s(io.get_executor(), std::atoi(argv[1]));
// ...
io.join();
} catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n";
}
}
¹ 参见示例Should the exception thrown by boost::asio::io_service::run() be caught?