c – 如何丢弃与boost :: asio一起发送的数据?
我正在编写一些使用boost :: asio类读取和写入串行设备的代码.但是,当在程序之间发送多个字符串时,我注意到在接收程序中,数据在写入串口时按顺序读取,而不是从其他程序发送数据 – 如果我开始读取数秒之后的数据,我不会得到我现在发送的值,而是之前发送的值.我假设这是由我如何设置我的boost :: asio :: serial_port引起的:
int main(int argc,char const *argv[]){ int baud=atoi(argv[1]); std::string pty=argv[2]; printf("Virtual device: %sn",pty.data()); printf("Baud rate: %dn",baud); boost::asio::io_service io; boost::asio::serial_port port(io,pty); port.set_option(boost::asio::serial_port_base::baud_rate(baud)); // counter that writes to serial port in 1s intervals int val=0; while (1){ std::string data=std::to_string(val); data+='n'; std::cout << data; write(port,boost::asio::buffer(data.c_str(),data.size())); sleep(1); val++; data.clear(); } port.close(); return 0; } 有一种方法可以在将新值发送到串行端口时强制将过去的数据丢弃(我假设应该在代码的write()部分完成)? 解决方法
Boost.Asio没有为刷新串口缓冲区提供更高级别的抽象.但是,这通常可以通过在串行端口
native_handle()上运行特定于平台的调用(例如
tcflush() 或
PurgeComm() )来实现.
每个串行端口都有一个接收和发送缓冲区,并且刷新操作在一个或两个缓冲区上.例如,如果连接了两个串行端口(/ dev / pts / 3和/ dev / pts / 4),并且程序A打开并写入/ dev / pts / 3,则它只能刷新与/ dev关联的缓冲区/ pts / 3(在/ dev / pts / 3上接收但未读取的数据,以及写入/ dev / pts / 3但未传输的数据).因此,如果程序B启动,打开/ dev / pts / 4,并且想要读取非陈旧数据,则程序B需要在打开串口后刷新/ dev / pts / 4的接收缓冲区. 这是在CentOs上运行的完整示例.当示例作为编写器运行时,它将每秒向串行端口写入一个按顺序递增的数字.当示例作为编写器运行时,它将读取五个数字,休眠5秒并每隔一次迭代刷新其读取缓冲区: #include <iostream> #include <vector> #include <boost/asio.hpp> #include <boost/thread.hpp> /// @brief Different ways a serial port may be flushed. enum flush_type { flush_receive = TCIFLUSH,flush_send = TCOFLUSH,flush_both = TCIOFLUSH }; /// @brief Flush a serial port's buffers. /// /// @param serial_port Port to flush. /// @param what Determines the buffers to flush. /// @param error Set to indicate what error occurred,if any. void flush_serial_port( boost::asio::serial_port& serial_port,flush_type what,boost::system::error_code& error) { if (0 == ::tcflush(serial_port.lowest_layer().native_handle(),what)) { error = boost::system::error_code(); } else { error = boost::system::error_code(errno,boost::asio::error::get_system_category()); } } /// @brief Reads 5 numbers from the serial port,then sleeps for 5 seconds,/// flushing its read buffer every other iteration. void read_main(boost::asio::serial_port& serial_port) { std::vector<unsigned char> buffer(5); for (bool flush = false;; flush = !flush) { std::size_t bytes_transferred = read(serial_port,boost::asio::buffer(buffer)); for (std::size_t i = 0; i < bytes_transferred; ++i) std::cout << static_cast<unsigned int>(buffer[i]) << " "; boost::this_thread::sleep_for(boost::chrono::seconds(5)); if (flush) { boost::system::error_code error; flush_serial_port(serial_port,flush_receive,error); std::cout << "flush: " << error.message() << std::endl; } else { std::cout << "noflush" << std::endl; } } } /// @brief Write a sequentially increasing number to the serial port /// every second. void write_main(boost::asio::serial_port& serial_port) { for (unsigned char i = 0; ; ++i) { write(serial_port,boost::asio::buffer(&i,sizeof i)); boost::this_thread::sleep_for(boost::chrono::seconds(1)); } } int main(int argc,char* argv[]) { boost::asio::io_service io_service; boost::asio::serial_port serial_port(io_service,argv[2]); if (!strcmp(argv[1],"read")) read_main(serial_port); else if (!strcmp(argv[1],"write")) write_main(serial_port); } 使用socat创建虚拟串行端口: $socat -d -d PTY: PTY: 2014/03/23 16:22:22 socat[12056] N PTY is /dev/pts/3 2014/03/23 16:22:22 socat[12056] N PTY is /dev/pts/4 2014/03/23 16:22:22 socat[12056] N starting data transfer loop with FDs [3,3] and [5,5] 启动读写示例: $./a.out read /dev/pts/3 & ./a.out write /dev/pts/4 [1] 12238 0 1 2 3 4 noflush 5 6 7 8 9 flush: Success 14 15 16 17 18 noflush 19 20 21 22 23 flush: Success 28 29 30 31 32 noflush 33 34 35 36 37 flush: Success 如在输出中所示,当读取器刷新其读取缓冲器时,仅在序列中跳过数字:3 4 noflush 5 6 7 8 9 flush 14 15. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |