⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smstraffic.cpp

📁 多线程串口接受程序,通过异步接受处理程序能对大数据量传输的串口,比如大型电信交换机计费系统,进行快速稳定的处理.
💻 CPP
字号:
// SmsTraffic.cpp: implementation of the CSmsTraffic class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SmsTraffic.h"
#include "SendMsg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

int gReadMessage(SM_PARAM * pMsg)
{
	if(pMsg == NULL)
		return 0;
	char szRecv[1024] = {0};

	memset(pMsg->szBuf,0,1024);
	//读应答数据
	int nLen = ReadComm(szRecv, 1024);

	SYSTEMTIME st;
	GetLocalTime(&st);
	sprintf(pMsg->szTime,"%.4d-%.2d-%.2d %.2d:%.2d:%.2d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
	if(nLen == 0)
		return 0;
	if(nLen > 1023)
		strncpy(pMsg->szBuf,szRecv,1023);
	else
		strcpy(pMsg->szBuf,szRecv);

	return 1;	
}

int gSendMessage(SM_PARAM *pMsg)
{
	if(pMsg == NULL)
		return 0;
	WriteComm(pMsg->szBuf, strlen(pMsg->szBuf));
	return 1;
}


CSmsTraffic::CSmsTraffic()
{
	m_nSendIn = 0;
	m_nSendOut = 0;
	m_nRecvIn = 0;
	m_nRecvOut = 0;

	m_hKillThreadEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
	m_hThreadKilledEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);

	::InitializeCriticalSection(&m_csSend);
	::InitializeCriticalSection(&m_csRecv);

	// 启动子线程
	::AfxBeginThread(SmThread, this, THREAD_PRIORITY_NORMAL);
}

CSmsTraffic::~CSmsTraffic()
{
	::SetEvent(m_hKillThreadEvent);			// 发出关闭子线程的信号
	::WaitForSingleObject(m_hThreadKilledEvent, INFINITE);	// 等待子线程关闭

	::DeleteCriticalSection(&m_csSend);
	::DeleteCriticalSection(&m_csRecv);

	::CloseHandle(m_hKillThreadEvent);
	::CloseHandle(m_hThreadKilledEvent);
}

// 将一条消息放入发送队列
void CSmsTraffic::PutSendMessage(SM_PARAM* pSmParam)
{
	::EnterCriticalSection(&m_csSend);

	::memcpy(&m_SmSend[m_nSendIn], pSmParam, sizeof(SM_PARAM));

	m_nSendIn++;
	if(m_nSendIn >= MAX_SM_SEND)  m_nSendIn = 0;

	::LeaveCriticalSection(&m_csSend);
}

// 从发送队列中取一条消息
BOOL CSmsTraffic::GetSendMessage(SM_PARAM* pSmParam)
{
	BOOL fSuccess = FALSE;

	::EnterCriticalSection(&m_csSend);

	if(m_nSendOut != m_nSendIn)
	{
		::memcpy(pSmParam, &m_SmSend[m_nSendOut], sizeof(SM_PARAM));

		m_nSendOut++;
		if(m_nSendOut >= MAX_SM_SEND)  m_nSendOut = 0;

		fSuccess = TRUE;
	}

	::LeaveCriticalSection(&m_csSend);

	return fSuccess;
}

// 将一条消息放入接收队列
void CSmsTraffic::PutRecvMessage(SM_PARAM* pSmParam)
{
	::EnterCriticalSection(&m_csRecv);

	::memcpy(&m_SmRecv[m_nRecvIn], pSmParam, sizeof(SM_PARAM));

	m_nRecvIn++;
	if(m_nRecvIn >= MAX_SM_RECV)  m_nRecvIn = 0;

	::LeaveCriticalSection(&m_csRecv);
}

// 从接收队列中取一条消息
BOOL CSmsTraffic::GetRecvMessage(SM_PARAM* pSmParam)
{
	BOOL fSuccess = FALSE;

	::EnterCriticalSection(&m_csRecv);

	if(m_nRecvOut != m_nRecvIn)
	{
		::memcpy(pSmParam, &m_SmRecv[m_nRecvOut], sizeof(SM_PARAM));

		m_nRecvOut++;
		if(m_nRecvOut >= MAX_SM_RECV)  m_nRecvOut = 0;

		fSuccess = TRUE;
	}

	::LeaveCriticalSection(&m_csRecv);

	return fSuccess;
}


UINT CSmsTraffic::SmThread(LPVOID lParam)
{
	CSmsTraffic* p = (CSmsTraffic *)lParam;	// this
	int i = 0, nMsg = 0;
	SM_PARAM SmParam[128];		// 消息缓冲区
	enum {
		stHaveRest,				// 休息,延时
		stGetSendMessage,		// 取一条待发送的消息
		stDoSendMessage,		// 发送消息
		stSendWaitIdle,			// 发送不成功,等待GSM就绪
		stDoRecvMessage,		// 接收消息
		stPutRecvMessage,		// 储存接收的消息	
		stExit					// 退出
	} nState;					// 处理过程的状态

	nState = stHaveRest;

	// 发送和接收处理的大循环
	while(nState != stExit)
	{
		switch(nState)
		{
		case stHaveRest:
			//::Sleep(theApp.nSendWaitTime);
			nState = stDoRecvMessage;
			break;
	//	case stGetSendMessage:
	//			if(p->GetSendMessage(&SmParam[0]))  nState = stDoSendMessage;
	//			else nState = stDoRecvMessage;
	//			break;
	//		case stDoSendMessage:
	//			if(::gSendMessage(&SmParam[0]))  nState = stDoRecvMessage;
	//			else nState = stSendWaitIdle;
	//			break;
	//		case stSendWaitIdle:
	//			::Sleep(1000);
	//			nState = stDoSendMessage;
	//			break;
	
		case stDoRecvMessage:
			nMsg = ::gReadMessage(SmParam);
			if(nMsg > 0)  
				nState = stPutRecvMessage;
			else 
				nState = stHaveRest;
			break;
		case stPutRecvMessage:
			for(i = 0; i < nMsg; i++)  
				p->PutRecvMessage(&SmParam[i]);
			nState = stHaveRest;			
			break;                
		}
		
		// 检测是否有关闭本线程的信号
		DWORD dwEvent = ::WaitForSingleObject(p->m_hKillThreadEvent, 20);
		if(dwEvent == WAIT_OBJECT_0)  nState = stExit;
	}

	// 置该线程结束标志
	::SetEvent(p->m_hThreadKilledEvent);

	return 9999;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -