boost::asio::async_write issue over serial channel

boost::asio::async_write issue over serial channel

本文关键字:over serial channel issue asio async boost write      更新时间:2023-10-16

我有一个客户端服务器应用程序,流程如下所示:

客户端在Windows端,不使用boost服务器在Linux端,使用boost客户端-服务器通过串行通道RS485通信。和服务器使用boost::asio::async_write .

client --> calls command with specific command_id --> server
client <-- sends acknowledgement                  <-- server
{server process the command, meanwhile the client is blocked for response}
client <-- sends response                         <-- server

有时客户端收到确认,但没有收到响应,即使响应是由服务器发送的。当客户端发送另一个命令时,客户端将接收到挂起的响应。

如果我使用boost::asio::write串行通信,根本没有问题。

下面是async_write 的代码片段
boost::asio::async_write(serial_port, boost::asio::buffer(&v_chunk[0], v_chunk.size()),
        boost::bind(&Serial_channel::async_write_callback, this, boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
io_serv->run();
io_serv->reset();

您使用io_service的方式将不起作用。首先,在服务事件循环停止之前,run函数不会返回。其次,如果你只是想把它用作"轮询器",那么你应该使用pollpoll_one(或者run_one)。

但是如果你这样做,它和做一个非异步的write调用是一样的,你会看到异步函数的好处。

参考@Joachim评论我已经改变了我的流程如下,它工作了。

boost::asio::async_write(serial_port, boost::asio::buffer(&v_chunk[0], v_chunk.size()),
        boost::bind(&Serial_channel::async_write_callback, this, boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
io_serv->run();
usleep(1000); // 1 millisecond delay
io_serv->reset();