[英]boost::asio SerialPort unable to receive data
使用異步時,我無法通過 boost::asio 中的串行端口接收數據。 當我使用同步例程時,我能夠接收數據。
代碼:
串口端口.cpp
bool SerialPort::read_async(std::uint32_t read_timeout)
{
try
{
if (read_timeout not_eq SerialPort::ignore_timeout)
this->read_timeout = read_timeout;//If read_timeout is not set to ignore_timeout, update the read_timeout else use old read_timeout
this->port.async_read_some(boost::asio::buffer(this->read_buffer.data(), this->read_buffer.size()),
boost::bind(&SerialPort::read_handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
return true;
}
catch (const std::exception& ex)
{
PLOG_ERROR << ex.what();
return false;
}
}
void SerialPort::read_handler(const boost::system::error_code& error, std::size_t bytes_transferred)
{
std::string received_data_buffer;
std::transform(this->read_buffer.begin(), this->read_buffer.begin() + bytes_transferred,
std::back_inserter(received_data_buffer), [](std::byte character) {
return static_cast<char>(character);
});
PLOG_INFO << "In Read Buffer : " << received_data_buffer;
}
bool SerialPort::open_port(void)
{
try
{
this->port.open(this->port_name);
return true;
}
catch (const std::exception& ex)
{
PLOG_FATAL << ex.what();
}
return false;
}
串口端口.hpp
class SerialPort
{
private:
boost::asio::io_context io;
boost::asio::serial_port port;
boost::asio::serial_port::native_handle_type native_port;
std::string port_name;
const static std::uint32_t READ_BUFFER_MAX_LENGTH{ 8096 };
std::array<std::byte, SerialPort::READ_BUFFER_MAX_LENGTH> read_buffer;//Used in synchronous read
void read_handler(
const boost::system::error_code& error, // Result of operation.
std::size_t bytes_transferred // Number of bytes read.
);
//boost::asio::deadline_timer timer;
public:
SerialPort() : io(), port(io), thread_sync_read()
{
}
~SerialPort();
bool open_port(void);
bool read_async(std::uint32_t read_timeout = SerialPort::ignore_timeout);
};
主文件
SerialPort sp;
int main()
{
sp.open_port("COM11");
sp.write_sync("Testing123");
sp.read_async();
while (true)
{
}
return 0;
}
據說您正在嘗試異步執行一些操作。
首先,混合同步和異步操作並不總是可取的。 某些服務/IO 對象可能包含假設其中之一的內部 state。
其次,異步操作需要運行io_service。 那不會發生。 您可以使其顯式而不是當前的while()
循環。
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
namespace asio = boost::asio;
using boost::system::error_code;
std::ostream PLOG_INFO(std::clog.rdbuf());
std::ostream PLOG_ERROR(std::clog.rdbuf());
std::ostream PLOG_FATAL(std::clog.rdbuf());
class SerialPort
{
public:
SerialPort()
: io_()
, port_(io_) /*, thread_sync_read()*/
{}
~SerialPort() = default;
bool open_port(std::string name);
static constexpr uint32_t ignore_timeout = -1;
bool read_async(std::uint32_t read_timeout = SerialPort::ignore_timeout);
void run() { io_.run(); }
private:
static constexpr uint32_t READ_BUFFER_MAX_LENGTH{8096};
asio::io_context io_;
asio::serial_port port_;
std::string port_name_;
uint32_t read_timeout_ = ignore_timeout;
// asio::deadline_timer timer;
std::array<std::byte, READ_BUFFER_MAX_LENGTH> read_buffer_;
void read_handler(error_code error, size_t bytes_transferred);
};
bool SerialPort::read_async(std::uint32_t read_timeout) {
try {
if (read_timeout != SerialPort::ignore_timeout)
read_timeout_ =
read_timeout; // If read_timeout is not set to ignore_timeout,
// update the read_timeout else use old
// read_timeout
port_.async_read_some(
asio::buffer(read_buffer_.data(), read_buffer_.size()),
boost::bind(&SerialPort::read_handler, this,
asio::placeholders::error,
asio::placeholders::bytes_transferred));
return true;
} catch (const std::exception& ex) {
PLOG_ERROR << ex.what() << std::endl;
return false;
}
}
void SerialPort::read_handler(error_code error, size_t bytes_transferred) {
std::string s;
std::transform(
read_buffer_.begin(), read_buffer_.begin() + bytes_transferred,
std::back_inserter(s),
[](std::byte character) { return static_cast<char>(character); });
PLOG_INFO << "In Read Buffer : " << s << " (" << error.message() << ")" << std::endl;
}
bool SerialPort::open_port(std::string name) {
try {
port_name_ = std::move(name);
port_.open(port_name_);
return true;
} catch (std::exception const& ex) {
PLOG_FATAL << ex.what() << std::endl;
return false;
}
}
SerialPort sp;
int main(int argc, char** argv) {
sp.open_port(argc > 1 ? argv[1] : "COM11");
// sp.write_sync("Testing123");
sp.read_async();
sp.run();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.