Reputation: 23
When I call async_write 2 times the second message isn't sent to the server. In write handler I call async_read and when I run my code, the program is stuck on read. In connection handler:
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));
In 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();
}
In write handler I call:
BA::post(io_context, boost::bind(&ssd::read_msg, clientSocketPtr));
And in read_msg I call async_read.
Output as text:
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"}
Upvotes: 2
Views: 407
Reputation: 23
I've done some research and solved my problem using strand and making a message queue. First of all, it is important to push messages to the queue and then call the function which will check if queue isn't empty. If it isn't, the code will process the message and call async_write
and right after this it will pop this message from message queue. In write handler code calls async_read
and right after this it checks if the queue isn't empty again. If it isn't, it calls write function.
Some pseudo code:
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()
}
}
Upvotes: 0
Reputation: 18359
You can only have one async_write
outstanding at a time. Note that async_write
is implemented in terms of async_write_some
, and the two writes could be interleaved.
Upvotes: 5