PipeClient.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #include "StdAfx.h"
  2. #include "PipeClient.h"
  3. #include "Utility.h"
  4. PER_IO_CONTEXT CPipeClient::m_IoRead;
  5. PER_IO_CONTEXT CPipeClient::m_IoWrite;
  6. CPipeClient::CPipeClient(LPCTSTR lpPipeName, DWORD dwMode)
  7. {
  8. m_hReadInst = INVALID_HANDLE_VALUE;
  9. m_bClientStop = FALSE;
  10. m_dwMode = dwMode;
  11. memset(m_szPipeName, 0, MAX_PATH*sizeof(TCHAR));
  12. memset(m_szWriteBuff, 0, 1024*sizeof(TCHAR));
  13. memset(m_szReceiveBuff, 0, 1024*sizeof(TCHAR));
  14. if ( lpPipeName )
  15. _stprintf_s(m_szPipeName, _T("%s"), lpPipeName);
  16. }
  17. CPipeClient::~CPipeClient(void)
  18. {
  19. StopWork();
  20. if ( m_hReadInst != INVALID_HANDLE_VALUE )
  21. CloseHandle(m_hReadInst);
  22. }
  23. BOOL CPipeClient::StartWork()
  24. {
  25. if ( !m_bClientStop )
  26. {
  27. BOOL bRet = TRUE;
  28. HANDLE hConnect = CreateThread(NULL, 0, ConnectThread, this, 0, NULL);
  29. HANDLE hReadMsg = CreateThread(NULL, 0, ReadMsgThread, this, 0, NULL);
  30. if ( hConnect == NULL /*|| hReadMsg == NULL */)
  31. bRet = FALSE;
  32. if ( hConnect )
  33. CloseHandle(hConnect);
  34. if ( hReadMsg )
  35. CloseHandle(hReadMsg);
  36. return bRet;
  37. }
  38. return TRUE;
  39. }
  40. DWORD CPipeClient::ConnectThread(LPVOID lpParam)
  41. {
  42. CPipeClient *pInstance = (CPipeClient*)lpParam;
  43. if ( !pInstance )
  44. return 0L;
  45. while(!pInstance->m_bClientStop)
  46. {
  47. if ( pInstance->m_hReadInst != INVALID_HANDLE_VALUE ) {
  48. // 1分钟检测;
  49. Sleep(60000);
  50. Utility::dprintf(_T("m_hReadInst 已存在\n"));
  51. continue;
  52. }
  53. // 等待10秒;
  54. if ( !WaitNamedPipe(pInstance->m_szPipeName, 10000) )
  55. {// 如果管道不存在,会立即返回而不考虑超时值,所以此处仍要Sleep;
  56. Utility::dprintf(_T("<%ld> WaitNamedPipe 失败\n"), Utility::g_WndInfo.dwProcessId);
  57. Sleep(10000);
  58. continue;
  59. }
  60. pInstance->m_hReadInst = CreateFile(
  61. pInstance->m_szPipeName, // pipe name
  62. GENERIC_READ | GENERIC_WRITE, // read and write access
  63. 0, // no sharing
  64. NULL, // default security attributes
  65. OPEN_EXISTING, // opens existing pipe
  66. FILE_FLAG_OVERLAPPED, // default attributes
  67. NULL); // no template file
  68. // 创建成功,退出;
  69. if ( pInstance->m_hReadInst != INVALID_HANDLE_VALUE )
  70. {
  71. // 管道连接成功,修改管道通信模式:message-read mode.
  72. BOOL fSuccess = SetNamedPipeHandleState(
  73. pInstance->m_hReadInst, // pipe handle
  74. &pInstance->m_dwMode, // new pipe mode
  75. NULL, // don't set maximum bytes
  76. NULL); // don't set maximum time
  77. if (!fSuccess) {
  78. Utility::dprintf(_T("SetNamedPipeHandleState failed. GLE=%d\n"), GetLastError() );
  79. CloseHandle(pInstance->m_hReadInst);
  80. }
  81. }
  82. else
  83. {
  84. // Exit if an error other than ERROR_PIPE_BUSY occurs.
  85. if ( GetLastError() != ERROR_PIPE_BUSY )
  86. {
  87. Utility::dprintf(_T("Could not open pipe. GLE=%d\n"), GetLastError() );
  88. }
  89. }
  90. }
  91. Utility::dprintf(_T("<%ld> ConnectThread 退出\n"), Utility::g_WndInfo.dwProcessId);
  92. return 0;
  93. }
  94. DWORD CPipeClient::ReadMsgThread(LPVOID lpParam)
  95. {
  96. DWORD cbRead = 0;
  97. BOOL bSuccess = FALSE;
  98. TCHAR chBuf[BUFSIZE];
  99. DWORD dwDataIndex = 0;
  100. DWORD dwError = 0;
  101. CPipeClient *pInstance = (CPipeClient*)lpParam;
  102. if ( !pInstance )
  103. return 0L;
  104. int i = 0;
  105. while(!pInstance->m_bClientStop)
  106. {
  107. if ( pInstance->m_hReadInst == INVALID_HANDLE_VALUE ) {
  108. Sleep(2000);
  109. continue;
  110. }
  111. //do
  112. {
  113. bSuccess = ReadFile(
  114. pInstance->m_hReadInst, // pipe handle
  115. m_IoRead.szBuffer, // buffer to receive reply
  116. BUFSIZE, // size of buffer
  117. &m_IoRead.dwBufferSize, // number of bytes read
  118. (OVERLAPPED*)&pInstance->m_IoRead); // not overlapped
  119. dwError = GetLastError();
  120. //if ( !bSuccess && (dwError = GetLastError()) != ERROR_MORE_DATA )
  121. // break;
  122. if ( WaitFinish(pInstance->m_hReadInst, &m_IoRead) )
  123. {
  124. }
  125. Utility::dprintf(_T("读取数据:Error=%ld, Len=%ld, Data=%s\n"), dwError, m_IoRead.m_Overlapped.InternalHigh, m_IoRead.szBuffer);
  126. //Utility::dprintf(_T("读取数据:%ld, %ld"), dwError, cbRead);
  127. #if 0
  128. TCHAR szMsg[8912] = {0};
  129. _stprintf_s(szMsg, _T("读取数据:%d, %ld, %ld, %s\n"), (int)bSuccess, dwError, cbRead, chBuf);
  130. OutputDebugString(szMsg);
  131. #endif
  132. // 追回数据;
  133. memcpy(pInstance->m_szReceiveBuff + dwDataIndex, chBuf, cbRead);
  134. dwDataIndex += cbRead;
  135. } //while ( !bSuccess ); // repeat loop if ERROR_MORE_DATA
  136. // 清空缓存数据;
  137. dwDataIndex = 0;
  138. memset(chBuf, 0, BUFSIZE*sizeof(TCHAR));
  139. memset(m_IoRead.szBuffer, 0, BUFSIZE);
  140. if ( bSuccess )
  141. {
  142. Utility::dprintf(_T("读取到的消息=%d"), sizeof(pInstance->m_szReceiveBuff));
  143. //Sleep(3000);
  144. Utility::dprintf(_T("读取到的消息=%s"), pInstance->m_szReceiveBuff);
  145. // 消息处理;
  146. // ...
  147. }
  148. else
  149. {
  150. //Utility::dprintf(_T("ReadFile from pipe failed. GLE=%d\n"), dwError );
  151. if ( dwError == ERROR_PIPE_NOT_CONNECTED || dwError == ERROR_BROKEN_PIPE)
  152. {
  153. Utility::dprintf("CloseHandle\n");
  154. CloseHandle(pInstance->m_hReadInst);
  155. pInstance->m_hReadInst = INVALID_HANDLE_VALUE;
  156. }
  157. #ifdef _DEBUG
  158. //Sleep(10000);
  159. #endif
  160. }
  161. memset(pInstance->m_szReceiveBuff, 0, BUFSIZE*sizeof(TCHAR));
  162. }
  163. Utility::dprintf(_T("<%ld> ReadMsgThread 退出\n"),Utility::g_WndInfo.dwProcessId);
  164. return 0;
  165. }
  166. BOOL CPipeClient::WaitFinish(HANDLE hPipe, PER_IO_CONTEXT *pIoContext)
  167. {
  168. #if 1
  169. bool bPendingIO = false;
  170. switch(GetLastError())
  171. {
  172. // 正在连接中;
  173. case ERROR_IO_PENDING:
  174. bPendingIO = true;
  175. break;
  176. // 已经连接;
  177. case ERROR_PIPE_CONNECTED:
  178. SetEvent(pIoContext->m_Overlapped.hEvent);
  179. break;
  180. }
  181. DWORD dwWait = -1;
  182. DWORD dwTransBytes = -1;
  183. // 等待读写操作完成;
  184. dwWait = WaitForSingleObject(pIoContext->m_Overlapped.hEvent,INFINITE);
  185. switch(dwWait)
  186. {
  187. case 0:
  188. if (bPendingIO)
  189. {
  190. // 获取Overlapped结果;
  191. if( GetOverlappedResult(hPipe, &pIoContext->m_Overlapped, &dwTransBytes, TRUE) == FALSE)
  192. {
  193. printf("ConnectNamedPipe failed %d\n",GetLastError());
  194. return -1;
  195. }
  196. }
  197. break;
  198. // 读写完成;
  199. case WAIT_IO_COMPLETION:
  200. break;
  201. }
  202. return 0;
  203. #else
  204. DWORD dwError=::GetLastError();
  205. DWORD dwWait = -1;
  206. DWORD dwTransBytes = -1;
  207. WaitForSingleObject(pIoContext->m_Overlapped.hEvent, INFINITE); // 等待异步操作完成;
  208. if (dwError == ERROR_IO_PENDING) {
  209. while (!::GetOverlappedResult(hPipe, &pIoContext->m_Overlapped, &dwTransBytes, false)) {
  210. dwError = ::GetLastError();
  211. if ( dwError == ERROR_IO_PENDING ) {
  212. Sleep(50);
  213. //Utility::dprintf("读等待:%ld", dwError);
  214. } else if ( dwError == ERROR_SUCCESS || dwError == ERROR_IO_INCOMPLETE ) {
  215. //Utility::dprintf("读完成:%ld,%ld,%ld", dwError, dwTransBytes, pIoContext->m_Overlapped.InternalHigh);
  216. break;
  217. } else {
  218. //Utility::dprintf("读错误:%ld", dwError);
  219. dwTransBytes = 0;
  220. return 0;
  221. }
  222. }
  223. }
  224. return 1;
  225. #endif
  226. }
  227. BOOL CPipeClient::SendMessage(PACKAGE &pak)
  228. {
  229. // 是否连接了服务端;
  230. if ( m_hReadInst == INVALID_HANDLE_VALUE )
  231. return FALSE;
  232. // 是否初始化了句柄;
  233. return FALSE;
  234. }
  235. BOOL CPipeClient::SendData(const TCHAR *lpszMsg, DWORD dwDataLen)
  236. {
  237. if ( m_hReadInst == INVALID_HANDLE_VALUE )
  238. return FALSE;
  239. static int i = 0;
  240. DWORD dwNumberOfBytesWritten = 0;
  241. char szMsg[255] = {0};//"你好----001";
  242. sprintf(szMsg, "发送内容:%d,%d", ::GetCurrentProcessId(), i++);
  243. BOOL fWrite = WriteFile(m_hReadInst,szMsg,strlen(szMsg),&dwNumberOfBytesWritten, NULL);//;&m_IoWrite.m_Overlapped);
  244. //WaitFinish(m_hReadInst, &m_IoWrite);
  245. if ( fWrite )
  246. {
  247. Utility::dprintf(_T("SendData:%s\n"),lpszMsg);
  248. }
  249. return TRUE;
  250. }