嗯,今天我们来结束boost的asio吧,如大家所想,既然asio是用来通信用的,那么自然也少不了关于串口的操作,对于串口,他比起网络来要简单得多,尤其又是在我们都明白asio的网络是怎么工作的情况下来理解串口基本都不需要理解的,同样的操作方式我们只是简单的换个 通信模式就完成了串口的操作。
关于boost的东西,我基本不会和大家说得很详细,因为关于这方面的细节网络上有不少资料,但是网上基本就是介绍里面怎么的组件功能和用法,却没有一个算是很完整的例子,所以我们这里基本就算是补全这个所谓的全面的例子而已,而这里也只是让大家知道,当我们想要使用这些东西的时候可以有的放矢的去查询资料,就比如,当我们想要通过网络来通信的时候,我们可能会想起boost里面好像有个组件是专门来用做这件事,于是我们就带着目的性的去查询这个组件的具体方式,想我们想要操作字符串的时候,我们会想起boost的里面的专门用来处理字符串的algorithm组件,而且还有功能更加强大的正则表达式,当我们想要操作操作系统相关例如文件系统那么我们则会想起boost的filesystem组件,当我们想要在我们程序中运用观察者模式的时候,可能我们会第一时间想起boost的signal组件等等,这些东西都很好用,我的程序基本就是STL和boost的东西组成的,因为这两者基本就可以满足我们基本的所有需求.
和前面的两讲一样,我们的框架都是基本如出一辙,所以关于串口的细节我也不多说,这里还是提供一个完整的类,大家如果工作中会用到串口操作的话,可以直接用他就行,当然如果自己想要重写一些定制的,那么在没有参考的情况下也可以参考。
//-----------------------------------------------------
#pragma once
#include <string>
#include <stdlib.h>
#include <iostream>
#include <memory>
#include <vector>
#include <boost/asio/serial_port.hpp>
#include <thread>
#include <Logger.h>
using namespace std;
typedef std::function<void(const std::string&)> SERIAL_FUN;
class HSerial_Port
{
public:
HSerial_Port();
virtual ~HSerial_Port();
void bindFun(SERIAL_FUN fun);
void Connect(const std::string &SerialName, unsigned port = 115200, bool isAsyni = true, int stopbit = 1);
//--------------------------------------
// 同步操作
int Send(const std::string& send);
int Read(std::string& str, size_t size = 8192);
//------------------------------------
//同步操作,主要用于通信指令上的操作
int write(char* sendmsg, size_t size);
std::vector<char> readAll();
//-------------------------------
// 异步操作
void postSend(const std::string& sendmsg);
void postReceive();
bool IsConnected();
void close();
bool is_open(){
return m_serial->is_open();
}
protected:
void read_handle(const boost::system::error_code& e, std::shared_ptr<std::vector<char>> read_msg);
void send_handle(const boost::system::error_code& e, const std::string& send_msg);
private:
std::shared_ptr<boost::asio::serial_port> m_serial;
boost::asio::io_service m_ios;
bool b_IsConnect;
SERIAL_FUN m_recall_fun;
std::shared_ptr<boost::asio::io_service::work> m_work;
std::thread m_thread;
std::string m_com_port;
unsigned m_baud_rate;
unsigned m_stop_bit;
bool b_is_asyn;
bool b_is_first{ true };
Logger g_logger;
};
//------------------------------------
#include "HSerial_Port.h"
#include <utility>
#include <boost/algorithm/string.hpp>
HSerial_Port::HSerial_Port() :m_recall_fun(nullptr), m_time_fun(nullptr)
m_work = std::shared_ptr<boost::asio::io_service::work>(new boost::asio::io_service::work(m_ios));
m_thread = std::thread([&](){m_ios.run(); });
g_logger.EnableConsole(true);
}
HSerial_Port::~HSerial_Port(){
if (m_thread.joinable()){
m_thread.join();
void HSerial_Port::Connect(const std::string &SerialName, unsigned port, bool isAsyni,int stopbit)
try{
m_serial = std::shared_ptr<boost::asio::serial_port>(new boost::asio::serial_port(m_ios, SerialName));
catch (...){
g_logger.log("Create Serial port fail......");
return;
m_serial->set_option(boost::asio::serial_port::baud_rate(port));
m_serial->set_option(boost::asio::serial_port::character_size(8));
m_serial->set_option(boost::asio::serial_port::flow_control(boost::asio::serial_port::flow_control::none));
m_serial->set_option(boost::asio::serial_port::parity(boost::asio::serial_port::parity::none));
if (stopbit == 2){
m_serial->set_option(boost::asio::serial_port::stop_bits(boost::asio::serial_port::stop_bits::two));
else if (stopbit == 1){
m_serial->set_option(boost::asio::serial_port::stop_bits(boost::asio::serial_port::stop_bits::one));
m_stop_bit = (stopbit;
m_com_port = SerialName;
m_baud_rate = port;
b_is_first = true;
b_is_asyn = isAsyni;
if (isAsyni){
postReceive();
void HSerial_Port::bindFun(SERIAL_FUN fun)
m_recall_fun = fun;
int HSerial_Port::Send(const std::string &send)
if(!IsConnected())
return false;
int size = m_serial->write_some(boost::asio::buffer(send, send.size()));
return size;
int HSerial_Port::Read(std::string &str, size_t size)
if(m_serial->is_open())
std::vector<char> v(size, 0); //8k
long long size = m_serial->read_some(boost::asio::buffer(v));
if (size == 0)
return 0;
str = std::string(&(v)[0]);
return 0;
int HSerial_Port::write(char* sendmsg, size_t size){
if (!IsConnected())
return false;
int n_size = m_serial->write_some(boost::asio::buffer(sendmsg,size));
return n_size;
std::vector<char> HSerial_Port::readAll(){
if (m_serial->is_open())
{
std::vector<char> v(8192, 0); //8k
return std::vector<char>();
return std::vector<char>(v.begin(),v.begin()+size);
bool HSerial_Port::IsConnected()
return true;
return false;
void HSerial_Port::close()
if (IsConnected())
m_serial->close();
void HSerial_Port::postSend(const std::string& sendmsg){
if (sendmsg.empty())
if (!m_serial->is_open()){
g_logger.log("Com close.......");
Connect(m_com_port, m_baud_rate,b_is_asyn,m_stop_bit);
m_serial->async_write_some(boost::asio::buffer(&sendmsg[0],sendmsg.size()), std::bind(&HSerial_Port::send_handle, this, std::placeholders::_1, sendmsg));
void HSerial_Port::postReceive(){
g_logger.log("Com unable open......");
std::shared_ptr<std::vector<char>> v(new std::vector<char>(8192, 0));
m_serial->async_read_some(boost::asio::buffer(*v), std::bind(&HSerial_Port::read_handle, this, std::placeholders::_1, v));
void HSerial_Port::read_handle(const boost::system::error_code& e, std::shared_ptr<std::vector<char>> read_msg){
if (e){
if (IsConnected()){
postReceive();
return;
}
else{
Connect(m_com_port, m_baud_rate,b_is_asyn,m_stop_bit);
g_logger.log("serial port close!!!!!");
std::string data = &((*read_msg)[0]);
if(m_recall_fun)
m_recall_fun(data);
postReceive();
void HSerial_Port::send_handle(const boost::system::error_code& e, const std::string& send_msg){
g_logger.log("serial port close!!!!!");
//-------------------------------------
使用起来相当的简单,比网络还要简单得多,如下:
//-------------------------------------------
HSerial_Port serial;
serial.Connect("COM1",9600,true,1);
serial.bindFun([](std::string& str){std::cout<<str<<std::endl;});
serial.PostSend("Hello,this is serialport");
愉快的工作吧.......
在上面的例子中我们使用了异步通信,所以我们只管发送就行,给他注册一个回调函数,当收到信息就会调用该函数,然后将信息打印出来就ok。
关于boost的asio就算是结束了,当然我没有讲得很细,所以如果有同学想要了解得更多,可以去网上查询资料,当然也可以直接问我。