【问题标题】:Problem with async_write two times in a rowasync_write 连续两次出现问题
【发布时间】:2020-08-18 08:32:09
【问题描述】:

当我调用 async_write 2 次时,第二条消息不会发送到服务器。在写处理程序中,我调用 async_read 并且当我运行我的代码时,程序被卡在读取状态。 在连接处理程序中:

clientSocketPtr->lowest_layer().set_option(BA::ip::tcp::no_delay(true));
clientSocketPtr->set_verify_mode(BA::ssl::verify_peer);
clientSocketPtr->set_verify_callback(BA::ssl::host_name_verification(ADDRESS));
clientSocketPtr->handshake(ssl_socket::client);
//first call with first message(76 bytes)
BA::post(io_context, boost::bind(&ssd::write_msg, message, clientSocketPtr)); 
//some code here
//second call with another message(160 bytes)
BA::post(io_context, boost::bind(&ssd::write_msg, message, clientSocketPtr)); 

在 write_msg 中:

void ssd::write_msg(ssd::Message &msg, ssd::ssl_socket *clientSocketPtr) {
//some code here
BA::async_write(*clientSocketPtr, BA::buffer(buf, bufSize), BA::transfer_exactly(bufSize), boost::bind(&ssd::write_handler,
BA::placeholders::error, BA::placeholders::bytes_transferred, clientSocketPtr)); 
io_context.run();
}

在我调用的写处理程序中:

BA::post(io_context, boost::bind(&ssd::read_msg, clientSocketPtr));

在 read_msg 中我调用 async_read。

输出为文本:

I20200818 11:17:38.633821  7417 message.hpp:53] 
Message type: 1
Message length: 70
Message: {"cli_type":"tarball","cli_version":"v2020.07.18","cmd":"cli_version"}
I20200818 11:17:38.637073  7417 sslconnection.cpp:77] Bytes sent: 76
I20200818 11:17:38.637115  7417 sslconnection.cpp:77] Bytes sent: 160
I20200818 11:17:38.640669  7417 sslconnection.cpp:109] Bytes recieved: 6
I20200818 11:17:38.640744  7417 sslconnection.cpp:122] Bytes recieved: 47
I20200818 11:17:38.640764  7417 sslconnection.cpp:128] 
Message length: 47
Message: {"cmd":"be_version","be_version":"v2020.07.15"}

【问题讨论】:

  • 将图片中的输出作为文本粘贴到您的问题中。
  • 请提供minimal reproducible example,猜测您正在调用套接字上的写入,而另一个写入仍在进行中
  • 当我调用 async_write 时,我使用完成条件,例如 transfer_exactly(bufSize)。我猜它不应该在前一个完成之前开始另一个写入
  • 当 async_read 完成后,是否开始另一个 async_read?
  • this 是我对 asio 所做的最好的时间投资之一。他谈到用股线保持秩序。

标签: c++ asynchronous networking boost boost-asio


【解决方案1】:

您一次只能有一个async_write 未完成。注意async_write是根据async_write_some实现的,两次写入可以交错。

【讨论】:

  • 完成条件同时维护2次写入,不是吗?
  • @DronovDmitrii 我不明白为什么会这样。他们都会调用 async_write_some。
  • 我该如何解决这个问题?我发送第一条消息,然后我期待回复。然后我必须发送第二条消息并且我必须收到响应。有一段时间我不明白如何实现这个,这让我卡住了。
  • 使用链,或使用分散/聚集(即写缓冲序列)。
  • 我明天试试,如果解决了我会发布答案
【解决方案2】:

我进行了一些研究并使用 strand 和创建消息队列解决了我的问题。首先,重要的是将消息推送到队列,然后调用检查队列是否为空的函数。如果不是,代码将处理该消息并调用async_write,然后它将从消息队列中弹出该消息。在写入处理程序代码调用async_read 之后,它会检查队列是否再次为空。如果不是,它会调用 write 函数。 一些伪代码:

msg_queue.push("First");
msg_queue.push("Second");
writeMsg();

writeMsg() {
    if (!msg_queue.empty()) {
    //proccess the message
    async_write(message);
    msg_queue.pop();
    } 
}

write_handler() {
    if(!error) {
        readMsg();
        if (!msg_queue.empty())
            write_msg()
    }

}

【讨论】:

    猜你喜欢
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 2022-12-16
    相关资源
    最近更新 更多