/*! @file
********************************************************************************
模 块名 : 通讯
文件名 : Factory.h
相关文件 : Factory.cpp
SerialPort.h SerialPort.cpp
文件实现功能 : 设计模式中的工厂模式,用来创建通讯.
作者 : 毛勇
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 : 否,会存在重复创建的问题,只能在一个线程中使用
异常时安全性 : 是,异常时时,会返回创建失败,并处理异常.
--------------------------------------------------------------------------------
备 注 : 使用智能指针保存通讯对象指针,使用了boost的asio(库在boost_1_43_0文件夹中)
--------------------------------------------------------------------------------
修 改记录 :
日 期 版本 修改人 修改内容
2010/06/10 1.0.0 毛勇 创建
*******************************************************************************/
#pragma once
#include "stdafx.h"
#include "Channel.h"
#include
#include
#include
#include
#include
using namespace std;
using boost::asio::serial_port;
class CTemperatureDlg;
/*! @class
********************************************************************************
类名称 : CSerialPort
功能 : 串口通讯类
异常类 : 无
--------------------------------------------------------------------------------
备注 :
典型用法 :
--------------------------------------------------------------------------------
作者 : 毛勇
*******************************************************************************/
class CSerialPort : public CChannel
{
public:
///////////////////////////////////////////////////////////// 构造和虚析构
CSerialPort(boost::asio::io_service& ioService,
const CCommAttr &commAttr,
CTemperatureDlg *pDlg
);
~CSerialPort();
public:
///////////////////////////////////////////////////////////// 公用方法
// [[ 功能组1
//! 处理接收到的数据
void HandleReceiveFrom(const boost::system::error_code& error,
size_t nBytesReceived
);
//! 处理发生数据
void HandleSendTo(const boost::system::error_code& /*error*/,
size_t /*bytes_sent*/
);
//! 直接发送数据
void Send(const string &strSend, const string &strSendType);
//! 申请资源
//int OpenPort();
//! 关闭端口
void Close();//退出();
// [[ 功能组1
private:
///////////////////////////////////////////////////////////// 私有方法
// [[ 功能组1
// [[ 功能组1
private:
///////////////////////////////////////////////////////////// 私有成员
boost::asio::io_service &m_ioService;
serial_port m_serialPort;
enum { MAX_LENGTH = 100 };
//! 接收缓冲区
char m_chRecvBuf[MAX_LENGTH];
//! 发生缓冲区
char m_chSendBuf[MAX_LENGTH];
};
==================================================================
==================================================================
串口cpp文件
==================================================================
==================================================================
#include "StdAfx.h"
#include "SerialPort.h"
#include "Resource.h"
#include "TemperatureDlg.h"
#include "Channel.h"
#include "TemperatureDlg.h"
CSerialPort::CSerialPort(boost::asio::io_service& ioService,
const CCommAttr &commAttr,
CTemperatureDlg *pDlg)
: m_ioService(ioService)
, CChannel (commAttr, pDlg) //初始化对话框指针
, m_serialPort(ioService, commAttr.strSerialPort.c_str())
{
// =========================================================================
// = 初始化波特率 fixme:波特率需要检查下是否是支持的波特率。通过表驱动检查比较简单
m_serialPort.set_option(serial_port::baud_rate(commAttr.nBaudRate));
// =========================================================================
// = 初始化流控制
if (0 == commAttr.strFlowControl.compare("none"))
{
m_serialPort.set_option(serial_port::flow_control(serial_port::flow_control::none));//无
}
else if (0 == commAttr.strFlowControl.compare("software"))
{
m_serialPort.set_option(serial_port::flow_control(serial_port::flow_control::software));//软件
}
else if (0 == commAttr.strFlowControl.compare("hardware"))
{
m_serialPort.set_option(serial_port::flow_control(serial_port::flow_control::hardware));//硬件
}
else
{
//出错,抛出异常?
}
// =========================================================================
// = 初始化奇偶校验
if (0 == commAttr.strParity.compare("none"))
{
m_serialPort.set_option(serial_port::parity(serial_port::parity::none));
}
else if (0 == commAttr.strParity.compare("odd"))
{
m_serialPort.set_option(serial_port::parity(serial_port::parity::odd));
}
else if (0 == commAttr.strParity.compare("even"))
{
m_serialPort.set_option(serial_port::parity(serial_port::parity::even));
}
else
{
}
// =========================================================================
// = 初始化停止位
if (0 == commAttr.strStopBits.compare("one"))
{
m_serialPort.set_option(serial_port::stop_bits(serial_port::stop_bits::one));
}
else if (0 == commAttr.strStopBits.compare("onepointfive"))
{
m_serialPort.set_option(serial_port::stop_bits(serial_port::stop_bits::onepointfive));
}
else if (0 == commAttr.strStopBits.compare("two"))
{
m_serialPort.set_option(serial_port::stop_bits(serial_port::stop_bits::two));
}
// =========================================================================
// = 初始化数据位
m_serialPort.set_option(serial_port::character_size(commAttr.nCharacterSize));
// =========================================================================
// = 开始读数据
m_serialPort.async_read_some(boost::asio::buffer(m_chRecvBuf, MAX_LENGTH),
boost::bind(&CSerialPort::HandleReceiveFrom,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
CSerialPort::~CSerialPort()
{
}
void
CSerialPort::HandleSendTo( const boost::system::error_code& /*error*/, size_t /*bytes_sent*/ )
{
m_serialPort.async_read_some(//async_receive_from
boost::asio::buffer(m_chRecvBuf, MAX_LENGTH),
boost::bind( &CSerialPort::HandleReceiveFrom,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
return;
}
void
CSerialPort::HandleReceiveFrom( const boost::system::error_code& error, size_t nBytesReceived )
{
if (!error && nBytesReceived > 0)
{
string strRecv(m_chRecvBuf, nBytesReceived);
m_pDlg->UpdateRecvMessage(strRecv); //更新主界面的接收发送
}
m_serialPort.async_read_some(boost::asio::buffer(m_chRecvBuf, MAX_LENGTH),
boost::bind( &CSerialPort::HandleReceiveFrom,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void
CSerialPort::Send(const string &strSend, const string &strSendType )
{
memcpy (m_chSendBuf, strSend.c_str(), strSend.length());
m_serialPort.async_write_some(boost::asio::buffer(m_chSendBuf, strSend.length()),
boost::bind(&CSerialPort::HandleSendTo,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void
CSerialPort::Close()
{
if (m_serialPort.is_open()) {
m_serialPort.close();
}
}
=====================================================================
=================== channel =========================================
/*! @file
********************************************************************************
模 块名 : 通讯模块 comm
文件名 : Channel.h
相关文件 : Channel.cpp
Product.h Product.cpp //通道
TcpServer.h TcpServer.cpp
UdpClient.h UdpClient.cpp
UdpServer.h UdpServer.cpp
SerialPort.h SerialPort.cpp
文件实现功能 : 存储软件版本号
作者 : 毛勇
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 : 是
异常时安全性 : 是
--------------------------------------------------------------------------------
备 注 : <其它说明>
--------------------------------------------------------------------------------
修 改记录 :
日 期 版本 修改人 修改内容
2010/05/28 1.0.0 毛勇 创建
*******************************************************************************/
#pragma once
#include
using std::string;
/*! @class
********************************************************************************
类名称 : CCommAttr
功能 : 通讯参数,用来创建连接所需要的参数。
异常类 : 无
--------------------------------------------------------------------------------
备注 :
典型用法 :
--------------------------------------------------------------------------------
作者 : 毛勇
*******************************************************************************/
class CCommAttr
{
public:
string strSerialPort;
int nBaudRate; //9600
string strParity;//none, odd, even。
string strStopBits; //停止位,构造参数为serial_port::stop_bits::type,enum类型,可以是one onepointfive two
string strFlowControl; //流控制 none software hardware
int nCharacterSize; //character_size 5,6,7,8
};
/*
父类: CChannel
子类: CTcpServer, CTcpClient, CUdpServer, CUdpClient 都是从 CChannel 派生
class CTcpServer: public CChannel
{
};
class CTcpClient: public CChannel
{
};
class CUdpServer: public CChannel
{
};
class CUdpClient: public CChannel
{
};
*/
class CTemperatureDlg;
//=============================================================================
//================= channel 类 相当于工厂模式中的 product 类==================
//=============================================================================
class CChannel
{
public:
///////////////////////////////////////////////////////////// 虚析构
virtual ~CChannel();
///////////////////////////////////////////////////////////// 保护构造函数
protected:
CChannel(const CCommAttr &commAttr, CTemperatureDlg *pDlg); //const CCommAttr &commAttr
public:
///////////////////////////////////////////////////////////// 公用方法
// [[ 功能组1
//virtual void Suspend() = 0;//暂停
//virtual void Startup() = 0;//启动
virtual void Close() = 0;//退出
virtual void Send(const string &strSend, const string &strSendType) = 0; //发送
// ]] 功能组1
protected:
//CCommAttr m_commAttr;
const CCommAttr m_commAttr;
CTemperatureDlg *m_pDlg;
};
==================================================================
#include "StdAfx.h"
#include "Channel.h"
//=============================================================================
//================= channel 类 相当于工厂模式中的 product 类==================
//=============================================================================
CChannel::CChannel( const CCommAttr &commAttr,
CTemperatureDlg *pDlg)
: m_commAttr(commAttr)
, m_pDlg(pDlg)
{
}
CChannel::~CChannel()
{
}
阅读(4550) | 评论(7) | 转发(0) |