Boost asio async_read_some 并读取整个数据

问题描述 投票:0回答:1

我最近问了一个关于 Boost Asio 的问题,并从其中一位成员那里得到了一个有趣的建议 https://coliru.stacked-crooked.com/a/6e17518e3a3850f7.

它使用

async_read_until
并读取直到出现 ' ',如果您正在读取未格式化的数据,这可以正常工作,但这不是最好的选择。

我了解到应该使用

async_read_some()
,所以在网上搜索后,看到一些示例代码,我尝试使用
async_read_some()
重现相同的结果。

下面是我的示例代码,但不幸的是我的尝试失败了,

#include <boost/asio.hpp>
#include <iostream>



namespace asio = boost::asio;
namespace this_coro = asio::this_coro;
using asio::ip::tcp;



template <typename T> using Defer = asio::deferred_t::as_default_on_t<T>;
using Socket = Defer<tcp::socket>;
using Acceptor = Defer<tcp::acceptor>;

void handler(
    const boost::system::error_code& error, // Result of operation.
    std::size_t bytes_transferred           // Number of bytes read.
)
{
    std::cout << bytes_transferred << std::endl;
    return;
}

asio::awaitable<void> session(Socket socket)
{
    auto ep = socket.remote_endpoint();
    std::cout << "New session for " << ep << "\n";

    size_t requests_handled = 0;
    for (std::string buf;; ++requests_handled)
    {
        char data[32] = { 0 };
        socket.async_read_some(boost::asio::buffer(data, sizeof(data)), handler);

    }
    std::cout << " -- Session " << ep << " handled " << requests_handled << " requests" << std::endl;
}

asio::awaitable<void> listener(uint16_t port)
{
    auto ex = co_await this_coro::executor;
    Acceptor acc(ex, { {}, port });
    for (;;)
    {
        co_spawn(ex, session(co_await acc.async_accept()), asio::detached);
    }
}

int main()
{
    asio::io_context ioc(1);
    co_spawn(ioc, listener(8989), asio::detached);

    ioc.run(); // single threaded, everything on main thread
}
  • 我无法从套接字读取任何数据
  • 我的完成处理程序从未被调用

除了我如何破坏工作示例之外,我还想知道如何读取整个传入数据,传入数据的大小各不相同,通过 tcp 套接字读取所有传入数据的最佳方法是什么?

我是 Boost Asio 和 C++ 的新手,我尽力自己找到解决方案,但不幸的是没有成功获得与

async_read_until
相同的结果并读取所有不同大小的传入 tcp 数据包。

谢谢

c++ asynchronous boost boost-asio
1个回答
0
投票

为什么要尝试以回调方式处理读取的输出?当你已经有一个协程时,这是没有意义的。只需使用已经是默认完成标记的

asio::deferred

 co_await socket.async_read_some(boost::asio::buffer(data, sizeof(data)));

这样,由于现在保证完成是协程的恢复,因此数组的生命周期不是问题,因为协程拥有堆栈帧。

© www.soinside.com 2019 - 2024. All rights reserved.