C++ (Qt)#include <iostream>#include <boost/bind.hpp>#include <boost/asio.hpp>#include <boost/program_options.hpp> namespace ba = boost::asio;namespace bs = boost::system;namespace po = boost::program_options; static const int timeInterval = 10; // ====================================================================================class reader{public: reader( ba::io_service &srv, ba::serial_port &port ) : m_srv( srv ), m_port( port ), m_timer( srv ), m_buf( 1024 ), m_total( 0 ) { m_port.async_read_some( ba::buffer( m_buf ), boost::bind( &reader::on_readed, this, ba::placeholders::error, ba::placeholders::bytes_transferred ) ); m_timer.expires_from_now( boost::posix_time::seconds( timeInterval ) ); m_timer.async_wait( boost::bind( &reader::on_timeout, this, ba::placeholders::error ) ); } protected: void on_readed( const bs::error_code &error, size_t bytes_transferred ) { if( error ) { if( error == ba::error::operation_aborted ) return; std::cerr << "Error: " << error.message() << std::endl; } else { m_total += bytes_transferred; m_port.async_read_some( ba::buffer( m_buf ), boost::bind( &reader::on_readed, this, ba::placeholders::error, ba::placeholders::bytes_transferred ) ); } } void on_timeout( const bs::error_code &error ) { if( error == ba::error::operation_aborted ) return; std::cout << "Speed: " << double( m_total ) / timeInterval << std::endl; m_total = 0; m_timer.expires_from_now( boost::posix_time::seconds( timeInterval ) ); m_timer.async_wait( boost::bind( &reader::on_timeout, this, ba::placeholders::error ) ); } ba::io_service &m_srv; ba::serial_port &m_port; ba::deadline_timer m_timer; std::vector<char> m_buf; int m_total;}; // ====================================================================================class writer{public: writer( ba::io_service &srv, ba::serial_port &port ) : m_srv( srv ), m_port( port ), m_buf( "Test string\n\r" ) { ba::async_write( m_port, ba::buffer( m_buf ), boost::bind( &writer::on_writed, this, ba::placeholders::error ) ); } protected: void on_writed( const bs::error_code &error ) { if( error ) { if( error == ba::error::operation_aborted ) return; std::cerr << "Error: " << error.message() << std::endl; } else { std::cout << "Writed data: " << m_buf.size() << " byte(s)." << std::endl; ba::async_write( m_port, ba::buffer( m_buf ), boost::bind( &writer::on_writed, this, ba::placeholders::error ) ); } } ba::io_service &m_srv; ba::serial_port &m_port; std::string m_buf;}; // ====================================================================================int main( int argc, char *argv[] ){ std::cout << "Serial port tester" << std::endl; std::string mode; std::string portname; int speed; po::options_description desc( "Options" ); desc.add_options() ( "help,h", "produce help message" ) ( "speed,s", po::value<int>( &speed )->default_value( 9600 ), "port speed" ) ( "mode", po::value<std::string>( &mode )->required(), "Mode: r | w" ) ( "portname", po::value<std::string>( &portname )->required(), "port name" ) ; po::positional_options_description pos_options; pos_options.add( "mode", 1 ); pos_options.add( "portname", 1 ); try { po::variables_map vm; po::store( po::command_line_parser( argc, argv ).options( desc ).positional( pos_options ).run(), vm ); if( vm.count( "help" ) ) { std::cout << desc << std::endl; return 1; } po::notify( vm ); } catch( po::error &e ) { std::cout << e.what() << std::endl; std::cout << desc << std::endl; return 10; } std::cout << "Mode: " << mode << std::endl << "Port: " << portname << std::endl << "Speed: " << speed << std::endl; try { ba::io_service io; ba::serial_port port( io ); port.open( portname ); if( !port.is_open() ) { std::cerr << "Error open serial port: " << portname << std::endl; return 2; } port.set_option( ba::serial_port_base::baud_rate( speed ) ); if( mode[ 0 ] == 'w' || mode[ 0 ] == 'W' ) { writer worker( io, port ); io.run(); } else { reader worker( io, port ); io.run(); } } catch( std::exception &e ) { std::cerr << e.what() << std::endl; return 3; } return 0;}