使用asio和协程实现echo服务器
使用boost asio和有栈协程实现echo服务器,session函数代表连接会话,可以看到session中的对异步完成操作的语法法如同写过程式函数一样简洁明了。和常见写法:用shared_ptr管理对象生存期、在异步操作完成函数中发起新的异步操作相比,很容易理解。
#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 <string_view>
using boost::asio::ip::tcp;
void session(tcp::socket&& socket)
{
boost::asio::spawn([socket_ = std::move(socket)](boost::asio::yield_context yield) mutable {
try {
boost::system::error_code ec;
char data[16];
for (;;) {
std::size_t n = socket_.async_read_some(boost::asio::buffer(data), yield[ec]);
if (!n) {
break;
}
boost::asio::async_write(socket_, boost::asio::buffer(data, n), yield);
}
} catch (std::exception& e) {
socket_.close();
}
});
}
int main(int argc, char* argv[])
{
try {
int port = 15999;
if (argc == 2) {
port = std::atoi(argv[1]);
}
boost::asio::io_context io_context;
boost::asio::spawn(io_context, [&](boost::asio::yield_context yield) {
tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), port));
for (;;) {
boost::system::error_code ec;
tcp::socket socket(io_context);
acceptor.async_accept(socket, yield[ec]);
if (!ec) {
session(std::move(socket));
}
}
});
io_context.run();
} catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
Posted 2020-10-14