嗯,今天我們來結束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就算是結束了,當然我沒有講得很細,是以如果有同學想要了解得更多,可以去網上查詢資料,當然也可以直接問我。