async_write 连续两次出现问题

Problem with async_write two times in a row

当我调用 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"}

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

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

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()
    }

}