I am trying to return an integer to the netcat(tcp) terminal, every time the message sent is Coop25, but this has generated a strange response on the terminal. The response is an instead of the integer and looks like this:
NETCAT TERMINAL:
Coop25
����
I have tried this function:
void tcp::tcp_session::do_write()
{
std::array<int, 1> test{1};
auto self(shared_from_this());
boost::asio::async_write(socket_, boost::asio::mutable_buffer(test.data(), test.size),
[this, self](boost::system::error_code ec, std::size_t /*length*/)
{
if (!ec)
{
do_read();
}
});
}
But when I try using some string this works:
std::string ret_mess_check{"blabla"}
const char* mess_to_reply = ret_mess_check.c_str();
do_write(mess_to_reply, strlen(mess_to_reply));
void tcp::tcp_session::do_write(const char* reply, std::size_t length)
{
auto self(shared_from_this());
boost::asio::async_write(socket_, boost::asio::buffer(reply, length),
[this, self](boost::system::error_code ec, std::size_t /*length*/)
{
if (!ec)
{
do_read();
}
});
}
After @sehe's considerations, I am doing something like this:
in a .hpp file, declaring the mv num_status_{-1};
boost::array<int, max_length> num_status_{-1};
in a .cpp file, defining the do_write() function, like this:
void dac_sim::tcp::tcp_session::do_write()
{
auto self(shared_from_this());
boost::asio::async_write(socket_, boost::asio::buffer(num_status_),
[this, self](boost::system::error_code ec, std::size_t /*length*/)
{
if (!ec)
{
do_read();
}
});
}
If I replace the member variable from an int to a string, everything works fine. With an int, the "����" still appears instead of -1 in this case.
You send /buffers/. Your code doesn't compile as given. For starters test.size
is a pointer-to-member-function. Even if you meant test.size()
then it would only send 1 byte, because test.size()
returns 1. Also, you're using mutable_buffer
when you don't need mutability. I'd write both incantations much simpler and much less error-prone:
void tcp::tcp_session::do_write(std::string_view reply) {
async_write(socket_, asio::buffer(reply),
[this, self = shared_from_this()](error_code ec, size_t /*length*/) {
if (!ec)
do_read();
});
}
void tcp::tcp_session::do_write() {
async_write(socket_, asio::buffer(test),
[this, self = shared_from_this()](error_code ec, size_t /*length*/) {
if (!ec)
do_read();
});
}
You can even combine the two generically:
void tcp::tcp_session::do_write(auto const& reply) {
async_write(socket_, asio::buffer(reply),
[this, self = shared_from_this()](error_code ec, size_t /*length*/) {
if (!ec)
do_read();
});
}
And it would work for strings, array<int, 1>
, std::vector<myComplicatedPodType>
and even double[32]
etc. etc.
You can even combine them in a buffer-sequence:
async_write(socket_, std::array{asio::buffer(test), asio::buffer(ret_mess_check)},
[this, self = shared_from_this()](error_code ec, size_t /*length*/) {
if (!ec)
do_read();
});
Another thing to note about the question code that you MUST NOT use a local variable (like your test
array) in an asynchronous operation, because it causes Undefined Behaviour because the buffer refers to an object whose lifetime ends before the asynchronous operation completes.