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

📄 smstraffic.cpp

📁 一个短信收发系统,需要连接一个串口短信发送装置,可以作为oa系统的一个模块.
💻 CPP
字号:
// SmsTraffic.cpp: implementation of the CSmsTraffic class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SmsTest.h"
#include "SmsTraffic.h"


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

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

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 nMsg;					// 收到短消息条数
	int nDelete;				// 目前正在删除的短消息编号
	int i;
	SM_PARAM SmParam[128];		// 短消息缓冲区
	enum {
		stHaveRest,				// 休息,延时
		stSendMessage,		    // 取一条待发送的短消息
	//	stDoSendMessage,		// 发送短消息
	//	stSendWaitIdle,			// 发送不成功,等待GSM就绪
		stDoRecvMessage,		// 接收短消息
		stPutRecvMessage,		// 储存接收的短消息
		stDeleteMessage,		// 删除短消息
		stDeleteWaitIdle,		// 删除不成功,等待GSM就绪
		stExit					// 退出
	} nState;					// 处理过程的状态

	nState = stHaveRest;

	//********************************************//
    int nLength;		// 串口收到的数据长度

	char* ptr;			// 内部用的数据指针
	char cmd[16];		// 命令串
	char ans[1024];		// 应答串
	char *temp;


	
	for(int j=0;j<1024;j++)
		ans[j]='\0';
     ptr=ans;
	 sprintf(cmd,"AT+CMGF=0\r");
	 WriteComm(cmd, strlen(cmd));	// 输出命令串

    ::Sleep(1000);
	nLength = ReadComm(ans, 1024);	// 读应答数据
	AfxMessageBox(ptr);

	//if((temp = strstr(ans, cmd)) !=NULL)
	//ptr=ptr+strlen(cmd);

    
	 if((temp = strstr(ptr, "OK")) ==NULL)
	 { 
		 AfxMessageBox("PDU mode 设置失败!");
		 nState = stExit;
		 //goto init;
	 }
   
	// 发送和接收处理的大循环
	while(nState != stExit)
	{	
		switch(nState)
		{
			case stHaveRest:
				::Sleep(1000);
				nState = stSendMessage;
				break;
			case stSendMessage:
				p->SendMessage();
				nState = stDoRecvMessage;
				break;
			case stDoRecvMessage:
				nMsg = ::gsmReadMessage(SmParam);
				if(nMsg > 0) 
				{
					AfxMessageBox("有短消息进入!");
					nState = stPutRecvMessage;
				}
				else nState = stHaveRest;
				break;
			case stPutRecvMessage:
				for(i = 0; i < nMsg; i++)  
					p->PutRecvMessage(&SmParam[i]);
				nState = stDeleteMessage;
				nDelete = 0;
				break;
			case stDeleteMessage:
				if(nDelete < nMsg)
				{
					if(::gsmDeleteMessage(SmParam[nDelete].index)) nDelete++;
					else nState = stDeleteWaitIdle;
					
				}
				else  nState = stHaveRest;
				break;
			case stDeleteWaitIdle:
				::Sleep(1000);
				nState = stDeleteMessage;
				break;
		}
		

		// 检测是否有关闭本线程的信号
		DWORD dwEvent = ::WaitForSingleObject(p->m_hKillThreadEvent, 20);
		if(dwEvent == WAIT_OBJECT_0)  nState = stExit;
	}

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

	return 9999;
}

 void CSmsTraffic::SendMessage()
{     
	 
	 
	    SM_PARAM SmParam;
	
		CString strTime;
		CString strNumber;
		CString strContent;
		CString strSmsc;

		
	    CString mSqlStr;
		

	    mSqlStr = "SELECT * FROM 短信记录表  WHERE 状态='未发送' OR 状态='发送失败'";
        
		
next:

		if (!msgDataSet.Open(AFX_DB_USE_DEFAULT_TYPE, mSqlStr))
		{
			AfxMessageBox("短信记录表打开失败!");
		     return;
		}
		if (!msgDataSet.IsEOF())
		{  
			
			strSmsc = theApp.m_strSmsc;
			strNumber=msgDataSet.m_number;
	        strContent=msgDataSet.m_content;
	       
	        CString strUnicode;
	        WCHAR wchar[1024];
	        int nCount = ::MultiByteToWideChar(CP_ACP, 0, strContent, -1, wchar, 1024);
	       
			
			if(nCount > 1&&nCount<=70)
			{
			
				::memset(&SmParam, 0, sizeof(SM_PARAM));

				if(strSmsc[0] == '+')  
					strSmsc = strSmsc.Mid(1);
				if(strNumber[0] == '+')  
					strNumber = strNumber.Mid(1);

	      
				if(strSmsc.Left(2) != "86")  
					strSmsc = "86" + strSmsc;
				if(strNumber.Left(2) != "86")  
					strNumber = "86" + strNumber;
			
			   
				::strcpy(SmParam.SCA, strSmsc);
		        ::strcpy(SmParam.TPA, strNumber);
		        ::strcpy(SmParam.TP_UD, strContent);
			
		
	        	SmParam.TP_PID = 0;
		        SmParam.TP_DCS = GSM_UCS2;
			
				if(::gsmSendMessage(&SmParam))  
			
				{
					msgDataSet.Edit();
					
					msgDataSet.m_status="已发送";
					msgDataSet.Update();
					msgDataSet.Requery();
		
				}
			 else 
				{
					msgDataSet.Edit();
				    msgDataSet.m_status="发送失败";
					msgDataSet.Update();
					msgDataSet.Requery();
					::Sleep(1000);
				}
				msgDataSet.Close();
			}
			goto next;
		}
		
	else
		{
			msgDataSet.Close();
		}
	
		
 }
		
		

 

⌨️ 快捷键说明

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