使用asio和boost fiber纤程实现echo服务器
boost fiber提供了编写异步程序的另一种方式,发起异步调用时切换上下文,由调度器迁移到其他纤程,当异步操作完成时,将原来纤程加入就绪队列,最终不再wait,成功执行完成操作,下文我们使用纤程实现echo服务器,可以看到会话session的语法和过程式调用一样简单。
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/write.hpp>
#include <iostream>
#include <memory>
#include <libs/fiber/examples/asio/yield.hpp>
#include <libs/fiber/examples/asio/detail/yield.hpp>
#include <libs/fiber/examples/asio/round_robin.hpp>
using boost::asio::ip::tcp;
void session(tcp::socket&& socket_)
{
using boost::fibers::asio::yield;
{
try {
boost::system::error_code ec;
char data[16];
for (;;) {
std::size_t n = socket_.async_read_some(boost::asio::buffer(data), yield);
if (!n) {
break;
}
boost::asio::async_write(socket_, boost::asio::buffer(data, n), yield);
}
} catch (std::exception& e) {
socket_.close();
}
}
}
void server(std::shared_ptr<boost::asio::io_context> io_ctx, int port);
int main(int argc, char* argv[])
{
try {
int port = 15999;
if (argc == 2) {
port = std::atoi(argv[1]);
}
std::shared_ptr<boost::asio::io_context> io_ctx = std::make_shared<boost::asio::io_context>();
boost::fibers::use_scheduling_algorithm<boost::fibers::asio::round_robin>(io_ctx);
using boost::fibers::asio::yield;
boost::fibers::fiber(server, io_ctx, port).detach();
io_ctx->run();
} catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
void server(std::shared_ptr<boost::asio::io_context> io_ctx, int port)
{
tcp::acceptor acceptor(*io_ctx, tcp::endpoint(tcp::v4(), port));
using boost::fibers::asio::yield;
for (;;) {
boost::system::error_code ec;
tcp::socket socket(*io_ctx);
acceptor.async_accept(socket, yield[ec]);
if (!ec) {
boost::fibers::fiber(session, std::move(socket)).detach();
}
}
}
Posted 2020-10-19