加协程
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
#pragma once
|
||||
|
||||
#include "ASIO_Utils.h"
|
||||
|
||||
#include <ucoro/awaitable.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Psc::asio_socket::coro {
|
||||
|
||||
struct TCP_Read_Result {
|
||||
std::vector<char> data;
|
||||
};
|
||||
|
||||
struct UDP_Read_Result {
|
||||
Sockaddr_In remote;
|
||||
std::vector<char> data;
|
||||
};
|
||||
|
||||
inline void throw_if_error(const asio::error_code& ec)
|
||||
{
|
||||
if (ec) {
|
||||
throw std::system_error(ec);
|
||||
}
|
||||
}
|
||||
|
||||
inline ucoro::awaitable<asio::ip::tcp::resolver::results_type>
|
||||
tcp_resolve(asio::ip::tcp::resolver& resolver,
|
||||
std::string host,
|
||||
std::uint16_t port)
|
||||
{
|
||||
struct Result {
|
||||
asio::error_code ec;
|
||||
asio::ip::tcp::resolver::results_type endpoints;
|
||||
};
|
||||
|
||||
auto result = co_await ucoro::callback_awaitable<Result>(
|
||||
[&resolver, host = std::move(host), port](auto done) mutable {
|
||||
resolver.async_resolve(
|
||||
host,
|
||||
std::to_string(port),
|
||||
[done = std::move(done)](const asio::error_code& ec,
|
||||
asio::ip::tcp::resolver::results_type endpoints) mutable {
|
||||
done(Result{ec, std::move(endpoints)});
|
||||
});
|
||||
});
|
||||
|
||||
throw_if_error(result.ec);
|
||||
co_return std::move(result.endpoints);
|
||||
}
|
||||
|
||||
inline ucoro::awaitable<asio::ip::tcp::endpoint>
|
||||
tcp_connect(asio::ip::tcp::socket& socket,
|
||||
const asio::ip::tcp::resolver::results_type& endpoints)
|
||||
{
|
||||
struct Result {
|
||||
asio::error_code ec;
|
||||
asio::ip::tcp::endpoint endpoint;
|
||||
};
|
||||
|
||||
auto result = co_await ucoro::callback_awaitable<Result>(
|
||||
[&socket, &endpoints](auto done) mutable {
|
||||
asio::async_connect(
|
||||
socket,
|
||||
endpoints,
|
||||
[done = std::move(done)](const asio::error_code& ec,
|
||||
const asio::ip::tcp::endpoint& endpoint) mutable {
|
||||
done(Result{ec, endpoint});
|
||||
});
|
||||
});
|
||||
|
||||
throw_if_error(result.ec);
|
||||
co_return result.endpoint;
|
||||
}
|
||||
|
||||
inline ucoro::awaitable<asio::ip::tcp::endpoint>
|
||||
tcp_connect(asio::ip::tcp::socket& socket,
|
||||
asio::ip::tcp::resolver& resolver,
|
||||
std::string host,
|
||||
std::uint16_t port)
|
||||
{
|
||||
auto endpoints = co_await tcp_resolve(resolver, std::move(host), port);
|
||||
co_return co_await tcp_connect(socket, endpoints);
|
||||
}
|
||||
|
||||
inline ucoro::awaitable<std::shared_ptr<asio::ip::tcp::socket>>
|
||||
tcp_accept(asio::ip::tcp::acceptor& acceptor)
|
||||
{
|
||||
auto socket = std::make_shared<asio::ip::tcp::socket>(acceptor.get_executor());
|
||||
|
||||
auto ec = co_await ucoro::callback_awaitable<asio::error_code>(
|
||||
[&acceptor, socket](auto done) mutable {
|
||||
acceptor.async_accept(
|
||||
*socket,
|
||||
[done = std::move(done)](const asio::error_code& ec) mutable {
|
||||
done(ec);
|
||||
});
|
||||
});
|
||||
|
||||
throw_if_error(ec);
|
||||
co_return socket;
|
||||
}
|
||||
|
||||
inline ucoro::awaitable<TCP_Read_Result>
|
||||
tcp_read_some(asio::ip::tcp::socket& socket,
|
||||
std::size_t max_size = 16 * 1024)
|
||||
{
|
||||
struct Result {
|
||||
asio::error_code ec;
|
||||
std::size_t size{};
|
||||
};
|
||||
|
||||
auto buffer = std::make_shared<std::vector<char>>(max_size);
|
||||
auto result = co_await ucoro::callback_awaitable<Result>(
|
||||
[&socket, buffer](auto done) mutable {
|
||||
socket.async_read_some(
|
||||
asio::buffer(*buffer),
|
||||
[done = std::move(done)](const asio::error_code& ec,
|
||||
std::size_t size) mutable {
|
||||
done(Result{ec, size});
|
||||
});
|
||||
});
|
||||
|
||||
throw_if_error(result.ec);
|
||||
buffer->resize(result.size);
|
||||
co_return TCP_Read_Result{std::move(*buffer)};
|
||||
}
|
||||
|
||||
inline ucoro::awaitable<std::size_t>
|
||||
tcp_write(asio::ip::tcp::socket& socket,
|
||||
std::string data)
|
||||
{
|
||||
struct Result {
|
||||
asio::error_code ec;
|
||||
std::size_t size{};
|
||||
};
|
||||
|
||||
auto buffer = std::make_shared<std::string>(std::move(data));
|
||||
auto result = co_await ucoro::callback_awaitable<Result>(
|
||||
[&socket, buffer](auto done) mutable {
|
||||
asio::async_write(
|
||||
socket,
|
||||
asio::buffer(*buffer),
|
||||
[done = std::move(done)](const asio::error_code& ec,
|
||||
std::size_t size) mutable {
|
||||
done(Result{ec, size});
|
||||
});
|
||||
});
|
||||
|
||||
throw_if_error(result.ec);
|
||||
co_return result.size;
|
||||
}
|
||||
|
||||
inline ucoro::awaitable<UDP_Read_Result>
|
||||
udp_receive_from(asio::ip::udp::socket& socket,
|
||||
std::size_t max_size = 16 * 1024)
|
||||
{
|
||||
struct Result {
|
||||
asio::error_code ec;
|
||||
std::size_t size{};
|
||||
asio::ip::udp::endpoint remote;
|
||||
};
|
||||
|
||||
auto buffer = std::make_shared<std::vector<char>>(max_size);
|
||||
auto remote = std::make_shared<asio::ip::udp::endpoint>();
|
||||
auto result = co_await ucoro::callback_awaitable<Result>(
|
||||
[&socket, buffer, remote](auto done) mutable {
|
||||
socket.async_receive_from(
|
||||
asio::buffer(*buffer),
|
||||
*remote,
|
||||
[done = std::move(done), remote](const asio::error_code& ec,
|
||||
std::size_t size) mutable {
|
||||
done(Result{ec, size, *remote});
|
||||
});
|
||||
});
|
||||
|
||||
throw_if_error(result.ec);
|
||||
buffer->resize(result.size);
|
||||
co_return UDP_Read_Result{endpoint_to_sockaddr(result.remote), std::move(*buffer)};
|
||||
}
|
||||
|
||||
inline ucoro::awaitable<std::size_t>
|
||||
udp_send_to(asio::ip::udp::socket& socket,
|
||||
std::string data,
|
||||
asio::ip::udp::endpoint remote)
|
||||
{
|
||||
struct Result {
|
||||
asio::error_code ec;
|
||||
std::size_t size{};
|
||||
};
|
||||
|
||||
auto buffer = std::make_shared<std::string>(std::move(data));
|
||||
auto result = co_await ucoro::callback_awaitable<Result>(
|
||||
[&socket, buffer, remote = std::move(remote)](auto done) mutable {
|
||||
socket.async_send_to(
|
||||
asio::buffer(*buffer),
|
||||
remote,
|
||||
[done = std::move(done)](const asio::error_code& ec,
|
||||
std::size_t size) mutable {
|
||||
done(Result{ec, size});
|
||||
});
|
||||
});
|
||||
|
||||
throw_if_error(result.ec);
|
||||
co_return result.size;
|
||||
}
|
||||
|
||||
inline ucoro::awaitable<std::size_t>
|
||||
udp_send_to(asio::ip::udp::socket& socket,
|
||||
std::string data,
|
||||
const Sockaddr_In& remote)
|
||||
{
|
||||
asio::error_code ec;
|
||||
auto address = asio::ip::make_address(remote.ip, ec);
|
||||
throw_if_error(ec);
|
||||
co_return co_await udp_send_to(
|
||||
socket,
|
||||
std::move(data),
|
||||
asio::ip::udp::endpoint(address, static_cast<unsigned short>(remote.port)));
|
||||
}
|
||||
|
||||
} // namespace Psc::asio_socket::coro
|
||||
Reference in New Issue
Block a user