boost-asio 相关问题

Boost.Asio是一个用于网络和低级I / O编程的跨平台C ++库,它使用现代C ++方法为开发人员提供一致的异步模型。

Boost 1.73.0 asio 在使用 get_executor 时出现错误

我的ubuntu版本是20.04LTS,Boost版本是1.73 这是我的代码: #include“服务器.h” #包括 服务器::服务器(boost::asio::io_context& io_context,无符号短...

回答 1 投票 0

了解多线程的 Boost.Asio Strand 行为

Win12、boost::asio 1.82.0、MSVC 2022(我使用了不同的编译器,c++ 14 和 c++ 20) 我尝试一步步理解iocontext。 现在我想使用很多线程(但我不想使用线程池...

回答 1 投票 0

Boost.Asio 的 io_context 在不运行 ioc.run() 的情况下出现意外行为 - 为什么它有效?

我尝试了解 iocontext 的工作原理,并创建了一个简单的程序来逐步更好地理解它。正如你所看到的,我什至不运行 ioc.run()。我相信这段代码不会做任何事情。 但是

回答 1 投票 0

设计 TCP 到 WebSocket

我计划拥有 TCP 到 WebSocket 隧道。多个 TCP 连接到一个 WebSocket 连接(我知道这需要多路复用,但一次只做一件事)。这意味着有一个 TCP 套接字正在监听

回答 1 投票 0

Boost.Beast 中缺少 Request 的模板参数

我尝试 http::request 的代表性代码是 #包括 命名空间 http = 野兽::http; 使用请求= http::request; 但对于最后一行我得到&...

回答 1 投票 0

Boost Asio 异步客户端

我正在尝试使用Boost asio编写一个异步客户端, 我写了下面的代码, #包括 #包括 #包括 我正在尝试使用 Boost asio 编写一个异步客户端, 我写了以下代码, #include <boost/asio.hpp> #include <boost/bind.hpp> #include <boost/asio/experimental/awaitable_operators.hpp> #include <boost/beast/http.hpp> #include <boost/json/src.hpp> namespace json = boost::json; namespace asio = boost::asio; namespace this_coro = asio::this_coro; using asio::ip::tcp; using boost::system::error_code; using namespace asio::experimental::awaitable_operators; #include <iostream> using namespace std; template <typename T> using Defer = asio::deferred_t::as_default_on_t<T>; using Socket = Defer<tcp::socket>; using Acceptor = Defer<tcp::acceptor>; using boost::asio::ip::tcp; class TCPClient { public: TCPClient(boost::asio::io_service& io_service, tcp::resolver::iterator endpoint_iterator) : io_service_(io_service), socket_(io_service) { connect(endpoint_iterator); } void write(const std::string& message) { io_service_.post(boost::bind(&TCPClient::do_write, this, message)); } void close() { io_service_.post(boost::bind(&TCPClient::do_close, this)); } private: void connect(tcp::resolver::iterator endpoint_iterator) { boost::asio::async_connect(socket_, endpoint_iterator, boost::bind(&TCPClient::handle_connect, this, boost::asio::placeholders::error)); } void handle_connect(const boost::system::error_code& error) { if (!error) { cout << "connected" << endl; write("Hello, World!"); read(); } else { cout << "connection failed" << endl; } } void do_write(const std::string& message) { boost::asio::async_write(socket_, boost::asio::buffer(message), boost::bind(&TCPClient::handle_write, this, boost::asio::placeholders::error)); } void handle_write(const boost::system::error_code& error) { if (!error) { cout << "write successfully" << endl; } else { cout << "write failed " << error << endl; } } void read() { socket_.async_read_some(boost::asio::buffer(data_, max_length), boost::bind(&TCPClient::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); //socket_.async_read_some(buf.prepare(1024), // boost::bind(&TCPClient::handle_read, this, // boost::asio::placeholders::error, // boost::asio::placeholders::bytes_transferred)); } void handle_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { std::cout << "Received: " << bytes_transferred << std::endl; read(); } else { // Handle the error std::cout << "read failed " << error << std::endl; } } void do_close() { socket_.close(); } boost::asio::io_service& io_service_; tcp::socket socket_; enum { max_length = 1024 }; char data_[max_length] = { 0 }; boost::asio::streambuf buf; }; int main() { boost::asio::io_service io_service; tcp::resolver resolver(io_service); tcp::resolver::iterator endpoint_iterator = resolver.resolve("localhost", "8989"); TCPClient client(io_service, endpoint_iterator); io_service.run(); while (1) {} return 0; } 客户端可以成功连接,并且正在调用处理程序。使用wireshark,我还可以看到 write() 函数发送“Hello, World”消息并收到回复,但写入或读取处理程序都没有被调用。 我尝试了不同的东西,看到了不同的示例代码,但我无法弄清楚。还尝试使用 coroutine 编写相同的代码,代码可以在下面找到,但是,我是异步套接字和 Boost Asio 的新手,我不确定我还在做什么(但正在努力实现) , #include <iostream> #include <boost/asio.hpp> #include <boost/asio/co_spawn.hpp> #include <boost/asio/detached.hpp> #include <boost/asio/use_awaitable.hpp> using boost::asio::ip::tcp; namespace asio = boost::asio; using asio::awaitable; using asio::co_spawn; using asio::detached; using asio::use_awaitable; awaitable<void> connectAndCommunicate() { try { asio::io_context io_context; tcp::socket socket(io_context); co_await socket.async_connect(tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 12345), use_awaitable); std::string message = "Hello, World!"; co_await asio::async_write(socket, asio::buffer(message), use_awaitable); char data[128]; std::size_t length = co_await socket.async_read_some(asio::buffer(data), use_awaitable); std::cout << "Received: " << std::string(data, length) << std::endl; } catch (const std::exception& e) { std::cerr << "Exception: " << e.what() << std::endl; } } int main() { asio::io_context io_context; co_spawn(io_context, connectAndCommunicate(), detached); io_context.run(); return 0; } 我希望更有经验的开发人员指出我的错误以及如何最好地做我想做的事情。 谢谢 第一版回顾 不要使用using命名空间 不要使用 boost::bind,当然也不要使用过时的 boost/bind.hpp include 不要包含大量不需要的标头,删除未使用的类型别名 使用您拥有的缩写命名空间 使用 io_context 代替已弃用的 io_service 不要传递对 io 上下文的引用;而是使用执行器 建议不要泄漏接口中的实现细节(将主机/端口作为构造函数参数,而不是某种特定类型的迭代器) 在链上时,不需要 post,因此在 handle_connect 中执行 do_write(),而不是 write() 现在我们的线路从 120 条减少到 69 条:Live On Coliru #include <boost/asio.hpp> #include <iostream> namespace asio = boost::asio; using namespace std::placeholders; using asio::ip::tcp; using boost::system::error_code; class TCPClient { public: TCPClient(asio::io_context& ioc, std::string const& host, std::string const& port) : socket_(ioc) { tcp::resolver resolver(ioc); connect(resolver.resolve(host, port)); } void write(std::string const& message) { post(socket_.get_executor(), std::bind(&TCPClient::do_write, this, message)); } void close() { post(socket_.get_executor(), std::bind(&TCPClient::do_close, this)); } private: void connect(tcp::resolver::iterator endpoint_iterator) { async_connect(socket_, endpoint_iterator, std::bind(&TCPClient::handle_connect, this, _1)); } void handle_connect(error_code ec) { if (!ec) { std::cout << "connected" << std::endl; do_write("Hello, World!"); read(); } else { std::cout << "connection failed (" << ec.message() << ")" << std::endl; } } void do_write(std::string const& message) { async_write(socket_, asio::buffer(message), std::bind(&TCPClient::handle_write, this, _1)); } void handle_write(error_code ec) { std::cout << "write " << ec.message() << std::endl; } void read() { socket_.async_read_some(asio::buffer(data_), std::bind(&TCPClient::handle_read, this, _1, _2)); // socket_.async_read_some(buf.prepare(1024), std::bind(&TCPClient::handle_read, this, _1, _2)); } void handle_read(error_code ec, size_t bytes_transferred) { std::cout << "Read " << ec.message() << " (" << bytes_transferred << ")" << std::endl; if (!ec) { std::cout << "Received: " << bytes_transferred << std::endl; read(); } else { // Handle the error } } void do_close() { socket_.close(); } tcp::socket socket_; std::array<char, 1024> data_{0}; // asio::streambuf buf; }; int main() { asio::io_context ioc; TCPClient client(ioc, "localhost", "8989"); ioc.run(); } 我可能无意中解决了一个我没有有意识提到的问题,但对我来说,它看起来只是有效(TM): 第二版审核 已经干净很多了!我建议 删除额外的io_context,你在一个协程中,根据定义有一个上下文。从this_coro获取执行者 使用deferred而不是use_awaitable来提高效率 不使用原始 C 数组 为了更接近第一个列表: 使用相同的缓冲区大小 还获取主机/端口信息并像第一个清单中那样解决它 循环读取 我们得到:在 Coliru 上生活 #include <boost/asio.hpp> #include <boost/asio/use_awaitable.hpp> #include <iostream> using boost::asio::ip::tcp; namespace asio = boost::asio; asio::awaitable<void> connectAndCommunicate(std::string host, std::string port) { try { auto ex = co_await asio::this_coro::executor; auto token = asio::deferred; tcp::socket s(ex); tcp::resolver resolver(ex); co_await async_connect(s, co_await resolver.async_resolve(host, port, token), token); std::string message = "Hello, World!"; co_await asio::async_write(s, asio::buffer(message), token); for (;;) { std::array<char, 1024> buf; auto length = co_await s.async_read_some(asio::buffer(buf), token); std::cout << "Received: " << quoted(std::string_view(buf.data(), length)) << std::endl; } } catch (boost::system::system_error const& se) { std::cerr << "Exception: " << se.code().message() << std::endl; } } int main() { asio::io_context ioc; co_spawn(ioc, connectAndCommunicate("127.0.0.1", "8989"), asio::detached); ioc.run(); } 我会考虑将 deferred 设置为默认执行器。讽刺的是,第一个代码清单定义了那些甚至不相关的类型别名:) Live On Coliru 未解之谜 事情被掩盖了,因为它们不是你问题的一部分: 链和输出消息队列(现在无论如何你都没有多个输出消息) 消息框架。如果您需要解释消息,async_read_some 是一个糟糕的方法。您将收到部分/串联的消息。这就是组合操作和动态缓冲区存在的原因。 错误处理。我稍微改进了它,但你需要意识到部分成功(特别是组合读取,但也许 async_read_some 可以返回字节 和 EOF 本身)

回答 1 投票 0

ASIO 使用 asio::async_write、asio::async_read 和 asio::async_read_until 通过 TCP 不断向服务器发送请求并从服务器获取响应

我正在开发一个 C++ 客户端/服务器应用程序,具有独立的 asio,无需 boost。我希望客户端应用程序能够不断从服务器获取响应并向服务器发送请求。

回答 1 投票 0

boost::asio中websocket的相对路径

我已经知道了 boost::asio 的基本用法,例如: std::size_t 缓存大小 = 1024; boost::asio::io_context global_io_context; boost::asio::ip::tcp::socket cur_socket(global_io_context);

回答 1 投票 0

Boost asio async_read_some 并读取整个数据

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

回答 1 投票 0

如何运行在类中实现的 2 个异步计时器

我希望第二个计时器在第二个计时器之后半秒开始工作,但是第二个计时器开始工作的那一刻,终端显示的内容与我想要的完全不同。我...

回答 1 投票 0

Boost Asio 同步与异步

我第一次使用 Boost Asio,我有一个接受多个连接的应用程序,每个连接都在单独的线程中,并将数据读/写到单个 TCP 套接字。 我对同步的理解遇到了...

回答 1 投票 0

io_context 不会阻塞 async_connect

我正在尝试使用 boost asio 运行一个简单的客户端、服务器脚本。 我的 connect() 函数的代码如下,在我的 main.cpp 中调用一次。 无效连接(){ 如果(!连接) ...

回答 1 投票 0

在 boost asio 中套接字显示为关闭

对于以下客户端代码 #包括 #包括 #包括 #包括 #包括 #包括 #inc...

回答 1 投票 0

boost::asio async_write 在 googletest 中交错

我一直在尝试使用 boost::asio 编写一个 tcp 服务器,该服务器将向任意数量的连接客户端发送数据,我一直在尝试使用 google test 编写一些测试。 我...

回答 1 投票 0

如何在 Asio 中取消组合异步操作?

我想使用组合的异步操作 asio::async_connect 并取消它,可能是在它进行的 basic_socket::async_connect 的各个调用之间。 以同样的方式,我想...

回答 1 投票 0

如何在使用 boost websocket_server_async 方法时使 aync_read 和 async_write 彼此独立?

我在我的项目中使用 boost websocket 并坚持使用这段代码,其中我的 async_write 仅当它从客户端读取某些内容时才执行。 我使用了 websocket_server_async 中的代码 下面...

回答 1 投票 0

如何使用带有多个签名的asio并发通道(&C++-20协程)

所以并发通道文档说: 通道支持的消息集由其模板参数指定 这意味着您可以发送不止一种消息类型。 (对吗?)

回答 1 投票 0

Boost.Asio即时数据传输至服务器

我遇到一个问题,除非套接字或发送关闭并且循环再次迭代以在套接字上传输更多数据,否则数据不会立即传输到服务器。 我测试了...

回答 1 投票 0

持久连接 boost.asio

我在 boost.asio 上有一个服务器和一个客户端。我希望会话在收到第一个数据包后继续接收新数据包并处理它们。如果递归调用start,程序会执行...

回答 1 投票 0

如何让 asio eventloop 从另一个线程调用 lambda?

假设一个线程正在运行asio事件循环,我怎样才能推迟在这个线程中调用lambda? #包括 #包括 #包括 int main() { 一个...

回答 1 投票 0

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