相关疑难解决方法(0)

如何保持增强asio异步读取持续活动

我正在构建一个必须发送请求和读取响应的tcp客户端,但也必须能够检测来自tcp服务器的不是对请求的响应的传入数据 - 服务器可以发起tx/rx序列.

什么是始终保持异步读取活动的最佳方法.我尝试了以下方法:

在我的"handle_connect"方法中,我启动了异步读取和异步写入.异步读取如下所示:


    size_t bytes_transferred = BUFFER_SIZE;
    boost::asio::async_read(m_socket,
        boost::asio::buffer(rcvbuf, bytes_transferred),
        boost::bind(&CClientSock::handle_read, 
        this,
        boost::asio::placeholders::error,
        boost::asio::placeholders::bytes_transferred));

异步写入填充缓冲区然后开始写入:


    boost::asio::async_write(m_socket,
        boost::asio::buffer(sndbuf, request_length),
        boost::bind(&CClientSock::handle_write, 
        this,
        boost::asio::placeholders::error,
        boost::asio::placeholders::bytes_transferred));

在异步写入处理程序中 - 由于异步读取已经启动,因此它什么都不做.

这不起作用.应该从服务器对客户端写入的响应中读取的数据永远不会触发异步读取处理程序.我实际上并不确定写入会执行......

可以这样做,因为读取和写入不按正常顺序排队吗?我是否必须开始读取,然后取消它,如果我需要开始写入?

c++ boost asynchronous

5
推荐指数
1
解决办法
4289
查看次数

Boost ASIO,SSL:串流如何帮助实施?

TLDR:Strands序列化在完成处理程序之间共享的资源:如何防止ssl :: stream实现对并发读写请求(stream :: ssl不是全双工)对SSL上下文(内部使用)的并发访问?请记住,strand仅序列化完成处理程序调用或读/写请求的原始队列。[感谢sehe帮助我更好地表达了这一点]


我花了整整一天的时间阅读有关ASIO,SSL和链的信息;主要在stackoverflow上(其中有一些非常详细且表达明确的解释,例如,为什么在使用boost :: asio时为什么需要每个连接使用绞链)和Boost文档;但有一点尚不清楚。

显然,链可以序列化同一链中的回调,因此也可以序列化对那些链共享的资源的访问。

但是在我看来,boost :: asio :: ssl :: stream的问题不在完成处理程序回调中,因为不是在SSL上下文上同时运行的回调,而是ssl :: stream的实现。 。

我不能确定在调用async_read_some和async_write_some时使用strands或在完成处理程序中使用strands会阻止io引擎同时在不同线程中的SSL上下文上运行。

显然,在调用async_read_some或async_write_some时使用绞合线将意味着不能同时在同一队列中进行读取和写入,但是我看不到如何阻止内部实现同时在不同的位置执行读取和写入操作如果封装的tcp :: socket同时准备好进行读取和写入,则将线程化。

在此问题的最后一个答案末尾的注释增强了asio-来自一个线程的SSL async_read和async_write声称并发写入ssl :: stream可能会出现段错误,而不仅仅是交错,这表明该实现未采取必要的锁定措施来防范并发访问。

除非实际的延迟套接字写操作绑定到将其排队的线程/线程(我看不到它是正确的,否则会破坏工作线程的有用性),否则我如何确定可以将读取排队并在同一ssl :: stream上进行写入,或者那样的方式可能是?

也许async_write_some立即使用SSL上下文处理所有数据,以生成加密数据,然后成为普通套接字写入,因此可以与同一链上的读取完成处理程序不冲突,但这并不意味着在完成处理程序在链上排队之前,它不会与内部实现套接字读取和解密冲突。不必介意可能发生的透明SSL会话重新协商...

我从中注意到:为什么在使用boost :: asio时为什么每个连接都需要链?“组合操作是唯一的,因为对流的中间调用是在处理程序的链中(如果存在的话)而不是在其中发起组合操作的链中调用。” 但是我不确定我指的是“流的中间调用”。这是否意味着:“该流实现中的任何后续处理”?我怀疑不是

最后,为什么,为什么?为什么ssl :: stream实现不使用没有冲突的廉价futex或其他锁?如果遵循绞线规则(隐式或显式),则成本几乎不存在,但否则将提供安全性。我问,因为我刚刚将Sutter,Stroustrup和其他产品的宣传转移了,C ++使一切变得更好,更安全,因此使用ssl :: stream似乎很容易遵循某些咒语,但几乎无法知道您的代码是否真正安全。

c++ ssl multithreading boost

5
推荐指数
1
解决办法
620
查看次数

提升:在异步调用中使用多次递归是否安全?

我是asio框架的新手,所以请善待.我调查了几个boost asio示例,发现人们使用这样的异步调用:

void read()
{
    async_read(socket_, boost::asio::buffer(&user_[0], user_.size()),
       boost::bind(&Connection::handle_user_read, this,
       placeholders::error, placeholders::bytes_transferred));
}
void handle_user_read(...)
{
    ...
    read();
    ...
}
Run Code Online (Sandbox Code Playgroud)

我认为这段代码不安全,因为它使用了多次递归.因此,当由于调用堆栈溢出而执行大量读取操作时,无法使用它.我在这方面并不是100%肯定,也无法找到其他人的类似想法.

有谁能详细解释一下这个?

c++ recursion boost-asio

5
推荐指数
1
解决办法
395
查看次数

一起使用 Boost::Asio 套接字异步和同步操作

我是 Boost C++ 新手,使用它来编写类似服务器的应用程序,我想知道是否可以同时使用 boost::asio::ip::tcp::socket::async_read_some(...)boost::asio::ip::tcp::socket::write_some(...).

在我的场景中,Connection 对象通过以下方式连续侦听:

    void Connection::doRead()
{
    auto self(shared_from_this());
    socket_.async_read_some(boost::asio::buffer(data_rx_, max_length),
        [this, self](boost::system::error_code ec, std::size_t length)
        {
          if (!ec)
          {
              afterReading(length);
              doRead();
          }
        });
}
Run Code Online (Sandbox Code Playgroud)

同时,异步函数回调(在不同线程中运行)可以socket_.read_write在 Connection 正在“读取”时调用。

我已经阅读了各种 Boost::Asio 文档,但从未涉及过这种情况。

这是允许的吗?如果不是,应该怎么做才能避免它?

编辑:

我已经按照建议阅读了各种答案,包括:为什么在使用 boost::asio 时每个连接都需要链?,但仍然找不到答案,因为它没有指定混合异步和同步(由不同线程调用)调用是否安全。

c++ sockets boost boost-asio

5
推荐指数
1
解决办法
2648
查看次数

asio::io_context 和 asio::thread_pool 有什么区别?

从多个线程调用其函数的anasio::thread_pool和 an之间有什么区别?我可以取代我该调用线程有?或者我需要某个地方吗?asio::io_contextrun()boost::thread_groupio_context::run()asio::thread_poolio_context

更新

当我使用 时asio::thread_pool,我还需要io_context使用套接字、定时器等吗?这两个thread_poolio_context是一个asio::execution_context。但是,文档说它io_context“提供核心 I/O 功能”。如果我只使用一个asio::thread_pool而没有一个,我会失去这些io_context吗?

c++ boost-asio asio

5
推荐指数
1
解决办法
758
查看次数

使用 boost 的 SSL asio 代码,async_write_some 挂起

我有一些使用 Boost 的 SSL ASIO 库的多线程代码。代码是多线程的,但是每个 SSL 连接都有一个互斥锁,并且对async_*函数的调用是通过持有互斥锁完成的。

我有时会看到我的代码停止运行。有一个卡住的线程。线程卡在bio_write. 堆栈跟踪如下所示:

#0  0x00000000010a974f in bio_write ()   

#1  0x00000000010a3529 in BIO_write ()

#2  0x000000000105fe72 in ssl3_write_pending ()

#3  0x0000000001060b02 in ssl3_write_bytes ()

#4  0x0000000000cce43a in boost::asio::ssl::detail::engine::do_write
(this=0x1e618a0, data=0x234c7b0, length=189) at
/usr/include/boost/asio/ssl/detail/impl/engine.ipp:294

#5  0x0000000000cce109 in boost::asio::ssl::detail::engine::perform(this=0x1e618a0, op=(int
(boost::asio::ssl::detail::engine::*)(boost::asio::ssl::detail::engine *
const, void *, std::size_t)) 0xcce3fc<boost::asio::ssl::detail::engine::do_write(void*, unsigned long)>,
data=0x234c7b0, length=189, ec=..., bytes_transferred=0x7fff8ad74d48) at
/usr/include/boost/asio/ssl/detail/impl/engine.ipp:219

#6  0x0000000000ccdd23 in boost::asio::ssl::detail::engine::write
(this=0x1e618a0, data=..., ec=..., bytes_transferred=@0x7fff8ad74d48: 0) at
/usr/include/boost/asio/ssl/detail/impl/engine.ipp:137

#7  0x0000000000dac504 in boost::asio::ssl::detail::write_op<boost::asio::mutable_buffers_1>::operator()
(this=0x7fff8ad74d20, eng=..., …
Run Code Online (Sandbox Code Playgroud)

ssl multithreading boost-asio

3
推荐指数
1
解决办法
2054
查看次数

asio :: async_write和strand

asio::async_write(m_socket, asio::buffer(buf, bytes),
                custom_alloc(m_strand.wrap(custom_alloc(_OnSend))));
Run Code Online (Sandbox Code Playgroud)

此代码是否保证async_write中的所有异步操作处理程序(对async_write_some的调用)都是通过strand调用的?(或者只是为了my_handler?)

c++ multithreading boost boost-asio

3
推荐指数
1
解决办法
1240
查看次数

boost :: asio在async_read中复制输入数据

最近,我从libevent切换到boost :: asio,一周后我注意到一件奇怪的事情:当我从客户端读取数据时,这些数据中的一些似乎是重复的,好像库不需要将其标记为已读(或类似的东西).我的"阅读"方法如下所示:

void client::doRead() {
    delete readBuffer; // getting rid of old data 
    readBuffer = new SerializedBuffer((uint) READ_BUFFER_SIZE);
    readBuffer->position(0);
    asio::async_read(socket, asio::buffer(readBuffer->bytes(), READ_BUFFER_SIZE),
            asio::transfer_at_least(1),
            boost::bind(&client::onRead, shared_from_this(), _1, _2));
}

std::mutex readMutex;
void client::onRead(const asio::error_code &err, size_t nbytes) {
    if (readMutex.try_lock()) {
        if (err) {
            stop();
            return;
        }

        readBuffer->rewind();
        uint limit = (uint) nbytes;
        readBuffer->limit(limit);

        // I've lost hope
        SerializedBuffer *sbuff = new SerializedBuffer(limit);
        memcpy(sbuff->bytes(), readBuffer->bytes(), limit);
        sbuff->limit(limit);

        // that's where I'm checking what I get
        Utils::print(sbuff->bytes(), limit);

        onReceivedData(shared_from_this(), sbuff);
        delete …
Run Code Online (Sandbox Code Playgroud)

c++ boost tcp client-server boost-asio

1
推荐指数
1
解决办法
309
查看次数

我不知道为什么使用 boost asio 的代码会导致错误

我创建了主 cpp 文件和三个类来创建异步服务器。 ServerService、 和Acceptor分别。然而,它们在构建过程中导致了错误,即使在 Visual Studio 2019 环境中没有错误。我试图修复这个错误,但大多数错误都发生在其他文件中,所以我自己都想不起来。

main

#include "Server.h"
#include <iostream>
#include <boost/asio.hpp>
#include <thread>
#include <atomic>
#include <memory>
#define DEFAULT_THREAD_SIZE 2;
using namespace boost;
int main()
{
 unsigned short port_num;
    std::cin >> port_num;
    try {
        Server srv;
        unsigned int threads = std::thread::hardware_concurrency() * 2;
        if (threads == 0) {
            threads = DEFAULT_THREAD_SIZE;
        }
        std::cout << "\nPort - " << port_num << "\nServer start\n";
        srv.Start(port_num, threads);
        while (1) {
            std::cin >> srv; …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-asio

0
推荐指数
1
解决办法
1267
查看次数