天天看點

boost::asio(3)

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

c++

繼續閱讀