SmsTraffic.cpp
上传用户:ynthgy
上传日期:2022-06-13
资源大小:1580k
文件大小:7k
源码类别:

手机短信编程

开发平台:

Visual C++

  1. // SmsTraffic.cpp: implementation of the CSmsTraffic class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "SmsTraffic.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. HANDLE hSmsThread; //短消息收发处理子线程句柄
  12. DWORD SmsThreadID; //短消息收发处理子线程标识符
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. // 构造函数
  17. CSmsTraffic::CSmsTraffic()
  18. {
  19. m_nSendIn = 0; //发送队列的输入指针置0
  20. m_nSendOut = 0; //发送队列的输出指针置0
  21. m_nRecvIn = 0; //接受队列的输入指针置0
  22. m_nRecvOut = 0; //接受队列的输出指针置0
  23. m_hKillThreadEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); //通知子线程关闭的事件
  24. m_hThreadKilledEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); //子线程宣告关闭的事件
  25. ::InitializeCriticalSection(&m_csSend); //初始化与发送相关的临界段
  26. ::InitializeCriticalSection(&m_csRecv); //初始化与接受相关的临界段
  27. //启动子线程
  28.     hSmsThread = CreateThread(0,0,SmThread,this,0,&SmsThreadID);
  29. //设置线程优先级
  30.     SetThreadPriority(hSmsThread, THREAD_PRIORITY_NORMAL);
  31. }
  32. // 析构函数
  33. CSmsTraffic::~CSmsTraffic()
  34. {
  35. ::SetEvent(m_hKillThreadEvent); // 发出关闭子线程的信号
  36. ::WaitForSingleObject(m_hThreadKilledEvent, INFINITE); // 等待子线程关闭
  37. ::DeleteCriticalSection(&m_csSend); //删除与发送相关的临界段
  38. ::DeleteCriticalSection(&m_csRecv); //删除与接受相关的临界段
  39. ::CloseHandle(m_hKillThreadEvent); //关闭通知子线程关闭的事件
  40. ::CloseHandle(m_hThreadKilledEvent); //关闭子线程宣告关闭的事件
  41. }
  42. // 将一条短消息放入发送队列
  43. void CSmsTraffic::PutSendMessage(SM_PARAM* pSmParam)
  44. {
  45. ::EnterCriticalSection(&m_csSend); //进入与发送相关的临界段
  46. ::memcpy(&m_SmSend[m_nSendIn], pSmParam, sizeof(SM_PARAM)); //将一条短消息放入发送队列
  47. m_nSendIn++; //发送队列的输入指针加1
  48. if(m_nSendIn >= MAX_SM_SEND) //发送队列的输入指针大于等于发送队列长度
  49. m_nSendIn = 0; //发送队列的输入指针置0
  50. ::LeaveCriticalSection(&m_csSend); //离开与发送相关的临界段
  51. }
  52. // 从发送队列中取一条短消息
  53. BOOL CSmsTraffic::GetSendMessage(SM_PARAM* pSmParam)
  54. {
  55. BOOL fSuccess = FALSE; //无短消息
  56. ::EnterCriticalSection(&m_csSend); //进入与发送相关的临界段
  57. if(m_nSendOut != m_nSendIn) //发送队列的输出指针不等于发送队列的输入指针
  58. {
  59. ::memcpy(pSmParam, &m_SmSend[m_nSendOut], sizeof(SM_PARAM)); //从发送队列中取一条短消息
  60. m_nSendOut++; //发送队列的输出指针加1
  61. if(m_nSendOut >= MAX_SM_SEND) //发送队列的输出指针大于等于发送队列长度
  62. m_nSendOut = 0; //发送队列的输出指针置0
  63. fSuccess = TRUE; //有短消息
  64. }
  65. ::LeaveCriticalSection(&m_csSend); //离开与发送相关的临界段、
  66. return fSuccess;
  67. }
  68. // 将一条短消息放入接收队列
  69. void CSmsTraffic::PutRecvMessage(SM_PARAM* pSmParam)
  70. {
  71. ::EnterCriticalSection(&m_csRecv); //进入与接受相关的临界段
  72. ::memcpy(&m_SmRecv[m_nRecvIn], pSmParam, sizeof(SM_PARAM)); //将一条短消息放入接受队列
  73. m_nRecvIn++; //接受队列的输入指针加1
  74. if(m_nRecvIn >= MAX_SM_RECV)  //接受队列的输入指针大于等于接受队列长度
  75. m_nRecvIn = 0; //接受队列的输入指针置0
  76. ::LeaveCriticalSection(&m_csRecv); //离开与接受相关的临界段
  77. }
  78. // 从接收队列中取一条短消息
  79. BOOL CSmsTraffic::GetRecvMessage(SM_PARAM* pSmParam)
  80. {
  81. BOOL fSuccess = FALSE; //无短消息
  82. ::EnterCriticalSection(&m_csRecv); //进入与接受相关的临界段
  83. if(m_nRecvOut != m_nRecvIn) //接受队列的输出指针不等于接受队列的输入指针
  84. {
  85. ::memcpy(pSmParam, &m_SmRecv[m_nRecvOut], sizeof(SM_PARAM)); //从接受队列中取一条短消息
  86. m_nRecvOut++; //接受队列的输出指针加1
  87. if(m_nRecvOut >= MAX_SM_RECV) //接受队列的输出指针大于等于接受队列长度
  88. m_nRecvOut = 0; //接受队列的输出指针置0
  89. fSuccess = TRUE; //有短消息
  90. }
  91. ::LeaveCriticalSection(&m_csRecv); //离开与接受相关的临界段
  92. return fSuccess;
  93. }
  94. // 短消息收发处理子线程
  95. DWORD CALLBACK CSmsTraffic::SmThread(LPVOID lParam)
  96. {
  97. CSmsTraffic* p=(CSmsTraffic *)lParam; // this
  98. int nMsg; // 收到短消息条数
  99. int nDelete; // 目前正在删除的短消息编号
  100. int i;
  101. int nCount = 0; //删除次数
  102. SM_PARAM SmParam[128]; // 短消息缓冲区
  103. //枚举类型
  104. enum {
  105. stHaveRest, // 休息,延时
  106. stGetSendMessage, // 取一条待发送的短消息
  107. stDoSendMessage, // 发送短消息
  108. stSendWaitIdle, // 发送不成功,等待GSM就绪
  109. stDoRecvMessage, // 接收短消息
  110. stPutRecvMessage, // 储存接收的短消息
  111. stDeleteMessage, // 删除短消息
  112. stDeleteWaitIdle, // 删除不成功,等待GSM就绪
  113. stExit // 退出
  114. } nState; // 处理过程的状态
  115. nState = stHaveRest;// 休息,延时
  116. // 发送和接收处理的大循环
  117. while(nState != stExit)
  118. {
  119. switch(nState)
  120. {
  121. case stHaveRest:// 休息,延时
  122. ::Sleep(1000);//延时1秒
  123. nState = stGetSendMessage;// 取一条待发送的短消息
  124. break;
  125. case stGetSendMessage:// 取一条待发送的短消息
  126. if(p->GetSendMessage(&SmParam[0]))// 从发送队列中取一条短消息
  127. nState = stDoSendMessage;//有短消息 发送短消息
  128. else 
  129. nState = stDoRecvMessage;//无短消息 接收短消息
  130. break;
  131. case stDoSendMessage:// 发送短消息
  132.                 if(::gsmSendMessage(&SmParam[0]))
  133.                 {
  134.                    ::Sleep(10000);//延时10s
  135.                    nState = stHaveRest;// 休息,延时
  136.                 }
  137. else
  138.                 {
  139.                   nState = stSendWaitIdle;// 发送不成功,等待GSM就绪
  140.                 }
  141. break;
  142. case stSendWaitIdle:// 发送不成功,等待GSM就绪
  143. ::Sleep(1000);//延时1s
  144. nState = stDoSendMessage;// 发送短消息
  145. break;
  146. case stDoRecvMessage:// 接收短消息
  147. nMsg = ::gsmReadMessage(SmParam);
  148. if(nMsg > 0)  
  149. nState = stPutRecvMessage;// 储存接收的短消息
  150. else 
  151. nState = stHaveRest;// 休息,延时
  152.                  break;
  153. case stPutRecvMessage:// 储存接收的短消息
  154. for(i = 0; i < nMsg; i++)  
  155. p->PutRecvMessage(&SmParam[i]);// 将一条短消息放入接收队列
  156. nState = stDeleteMessage;// 删除短消息
  157. nDelete = 0;
  158. break;
  159. case stDeleteMessage:// 删除短消息
  160. if(nDelete < nMsg)
  161. {
  162. if(::gsmDeleteMessage(SmParam[nDelete].index) || (nCount>=3))
  163. {
  164. nCount = 0;
  165. nDelete++;
  166. }
  167. else 
  168. {
  169. nState = stDeleteWaitIdle;
  170. }
  171. }
  172. else  
  173. nState = stHaveRest;// 休息,延时
  174. break;
  175. case stDeleteWaitIdle:// 删除不成功,等待GSM就绪
  176. ::Sleep(1000);//延时1s
  177. nState = stDeleteMessage;// 删除短消息
  178. ++nCount;
  179. break;
  180. }
  181. // 检测是否有关闭本线程的信号            //通知子线程关闭的事件
  182. DWORD dwEvent = ::WaitForSingleObject(p->m_hKillThreadEvent, 20);
  183. if(dwEvent == WAIT_OBJECT_0)  
  184. nState = stExit;
  185. }
  186. // 置该线程结束标志
  187. ::SetEvent(p->m_hThreadKilledEvent);//子线程宣告关闭的事件
  188. return 9999;
  189. }