PipeClient.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include "StdAfx.h"
  2. #include "PipeClient.h"
  3. #include "Utility.h"
  4. std::string CPipeClient::m_LastData;
  5. PER_IO_CONTEXT CPipeClient::m_IoRead;
  6. PER_IO_CONTEXT CPipeClient::m_IoWrite;
  7. CPipeClient::CPipeClient(LPCTSTR lpPipeName, DWORD dwMode)
  8. {
  9. m_hPipeInst = INVALID_HANDLE_VALUE;
  10. m_bClientStop = FALSE;
  11. m_dwMode = dwMode;
  12. memset(m_szPipeName, 0, MAX_PATH*sizeof(TCHAR));
  13. if ( lpPipeName )
  14. _stprintf_s(m_szPipeName, _T("%s"), lpPipeName);
  15. }
  16. CPipeClient::~CPipeClient(void)
  17. {
  18. StopWork();
  19. if ( m_hPipeInst != INVALID_HANDLE_VALUE )
  20. CloseHandle(m_hPipeInst);
  21. }
  22. BOOL CPipeClient::StartWork()
  23. {
  24. if ( !m_bClientStop )
  25. {
  26. BOOL bRet = TRUE;
  27. HANDLE hConnect = CreateThread(NULL, 0, ConnectThread, this, 0, NULL);
  28. HANDLE hReadMsg = CreateThread(NULL, 0, ReadMsgThread, this, 0, NULL);
  29. if ( hConnect == NULL || hReadMsg == NULL )
  30. bRet = FALSE;
  31. if ( hConnect )
  32. CloseHandle(hConnect);
  33. if ( hReadMsg )
  34. CloseHandle(hReadMsg);
  35. return bRet;
  36. }
  37. return TRUE;
  38. }
  39. DWORD CPipeClient::ConnectThread(LPVOID lpParam)
  40. {
  41. CPipeClient *pInstance = (CPipeClient*)lpParam;
  42. if ( !pInstance )
  43. return 0L;
  44. while(!pInstance->m_bClientStop)
  45. {
  46. if ( pInstance->m_hPipeInst != INVALID_HANDLE_VALUE ) {
  47. // 1分钟检测;
  48. Sleep(60000);
  49. Utility::dprintf(_T("m_hPipeInst 已存在\n"));
  50. continue;
  51. }
  52. // 等待10秒;
  53. if ( !WaitNamedPipe(pInstance->m_szPipeName, 10000) )
  54. {// 如果管道不存在,会立即返回而不考虑超时值,所以此处仍要Sleep;
  55. Utility::dprintf(_T("<%ld> WaitNamedPipe 失败\n"), Utility::g_WndInfo.dwProcessId);
  56. Sleep(10000);
  57. continue;
  58. }
  59. pInstance->m_hPipeInst = CreateFile(
  60. pInstance->m_szPipeName, // pipe name
  61. GENERIC_READ | GENERIC_WRITE, // read and write access
  62. 0, // no sharing
  63. NULL, // default security attributes
  64. OPEN_EXISTING, // opens existing pipe
  65. FILE_FLAG_OVERLAPPED, // default attributes
  66. NULL); // no template file
  67. // 创建成功,退出;
  68. if ( pInstance->m_hPipeInst != INVALID_HANDLE_VALUE )
  69. {
  70. // 管道连接成功,修改管道通信模式:message-read mode.
  71. BOOL fSuccess = SetNamedPipeHandleState(
  72. pInstance->m_hPipeInst, // pipe handle
  73. &pInstance->m_dwMode, // new pipe mode
  74. NULL, // don't set maximum bytes
  75. NULL); // don't set maximum time
  76. if (!fSuccess) {
  77. Utility::dprintf(_T("SetNamedPipeHandleState failed. GLE=%d\n"), GetLastError() );
  78. CloseHandle(pInstance->m_hPipeInst);
  79. pInstance->m_hPipeInst = INVALID_HANDLE_VALUE;
  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. CPipeClient *pInstance = (CPipeClient*)lpParam;
  97. if ( !pInstance )
  98. return 0L;
  99. int i = 0;
  100. DWORD dwError = 0;
  101. BOOL bSuccess = FALSE;
  102. while(!pInstance->m_bClientStop)
  103. {
  104. if ( pInstance->m_hPipeInst == INVALID_HANDLE_VALUE ) {
  105. Sleep(5000);
  106. continue;
  107. }
  108. #if 1 // 分配足够大的缓冲,保证C/S两端通信内容不超过该大小;
  109. bSuccess = ReadFile(pInstance->m_hPipeInst, m_IoRead.szBuffer, BUFSIZE, &m_IoRead.dwBufferSize, (OVERLAPPED*)&pInstance->m_IoRead);
  110. if ( bSuccess )
  111. {
  112. // 打印结果;
  113. Utility::dprintf(_T("读取数据:Error=%ld, Len=%ld, Data=%s\n"), dwError, m_IoRead.m_Overlapped.InternalHigh, m_IoRead.szBuffer);
  114. // 处理结果;
  115. }
  116. else
  117. {
  118. // 等待完成;
  119. if ( !WaitFinish(pInstance->m_hPipeInst, &m_IoRead) )
  120. {
  121. // 出现错误;
  122. Utility::dprintf("CloseHandle\n");
  123. CloseHandle(pInstance->m_hPipeInst);
  124. pInstance->m_hPipeInst = INVALID_HANDLE_VALUE;
  125. }
  126. else
  127. {
  128. // 打印结果;
  129. Utility::dprintf(_T("读取数据:Error=%ld, Len=%ld, Data=%s\n"), dwError, m_IoRead.m_Overlapped.InternalHigh, m_IoRead.szBuffer);
  130. // 处理结果;
  131. }
  132. }
  133. // 重置Buffer;
  134. memset(m_IoRead.szBuffer, 0, BUFSIZE);
  135. #else // 分配的缓冲区,不足以一次性存储C/S两端的通信内容时;
  136. do
  137. {
  138. bSuccess = ReadFile(pInstance->m_hPipeInst, m_IoRead.szBuffer, BUFSIZE, &m_IoRead.dwBufferSize, (OVERLAPPED*)&pInstance->m_IoRead);
  139. if ( bSuccess )
  140. {
  141. // 打印结果;
  142. dwError = GetLastError();// 此时bSuccess为True,但GetLastError仍为ERROR_MORE_DATA属于正常现象;
  143. m_LastData.append((char*)m_IoRead.szBuffer, m_IoRead.m_Overlapped.InternalHigh);
  144. // 处理结果;
  145. }
  146. else
  147. {
  148. dwError = GetLastError();
  149. if ( dwError == ERROR_MORE_DATA )
  150. {// 如果立即返回,没有IO PENDING;
  151. // 将当前数据保存;
  152. m_LastData.append((char*)m_IoRead.szBuffer, m_IoRead.m_Overlapped.InternalHigh);
  153. }
  154. else if ( dwError == ERROR_IO_PENDING )
  155. {
  156. DWORD dwWait = -1;
  157. DWORD dwTransBytes = -1;
  158. // 等待读写操作完成;
  159. dwWait = WaitForSingleObject(m_IoRead.m_Overlapped.hEvent,INFINITE);
  160. switch(dwWait)
  161. {
  162. case 0:
  163. // 获取Overlapped结果;
  164. if( GetOverlappedResult(pInstance->m_hPipeInst, &m_IoRead.m_Overlapped, &dwTransBytes, TRUE) == FALSE)
  165. {
  166. dwError = GetLastError();
  167. if ( dwError == ERROR_MORE_DATA )
  168. {
  169. m_LastData.append((char*)m_IoRead.szBuffer, m_IoRead.m_Overlapped.InternalHigh);
  170. }
  171. else
  172. {
  173. Utility::dprintf(_T("GetOverlappedResult:Error=%ld"), dwError);
  174. }
  175. }
  176. else
  177. {
  178. bSuccess = TRUE;
  179. Utility::dprintf(_T("GetOverlappedResult:Error=%ld"), GetLastError());
  180. m_LastData.append((char*)m_IoRead.szBuffer, m_IoRead.m_Overlapped.InternalHigh);
  181. }
  182. break;
  183. // 读写完成;
  184. case WAIT_IO_COMPLETION:
  185. break;
  186. }
  187. }
  188. else if ( dwError == ERROR_PIPE_CONNECTED )
  189. {// 管道的另一端有一个过程;
  190. DWORD dwWait = -1;
  191. DWORD dwTransBytes = -1;
  192. SetEvent(m_IoRead.m_Overlapped.hEvent);
  193. Utility::dprintf(_T("管道的另一端有一个过程:ERROR_PIPE_CONNECTED\n"));
  194. dwWait = WaitForSingleObject(m_IoRead.m_Overlapped.hEvent,INFINITE);
  195. }
  196. }
  197. // 清空缓存数据;
  198. memset(m_IoRead.szBuffer, 0, BUFSIZE);
  199. } while ( !bSuccess ); // repeat loop if ERROR_MORE_DATA
  200. Utility::dprintf(_T("读取数据:Error=%ld, Len=%ld, Data=%s\n"), dwError, m_LastData.size(), m_LastData.data());
  201. m_LastData.clear();
  202. #endif
  203. }
  204. Utility::dprintf(_T("<%ld> ReadMsgThread 退出\n"),Utility::g_WndInfo.dwProcessId);
  205. return 0;
  206. }
  207. BOOL CPipeClient::WaitFinish(HANDLE hPipe, PER_IO_CONTEXT *pIoContext)
  208. {
  209. bool bPendingIO = false;
  210. switch(GetLastError())
  211. {
  212. // 正在连接中;
  213. case ERROR_IO_PENDING:
  214. bPendingIO = true;
  215. break;
  216. case ERROR_MORE_DATA:
  217. break;
  218. // 已经连接;
  219. case ERROR_PIPE_CONNECTED:
  220. SetEvent(pIoContext->m_Overlapped.hEvent);
  221. break;
  222. }
  223. DWORD dwWait = -1;
  224. DWORD dwTransBytes = -1;
  225. // 等待读写操作完成;
  226. dwWait = WaitForSingleObject(pIoContext->m_Overlapped.hEvent,INFINITE);
  227. switch(dwWait)
  228. {
  229. case 0:
  230. if (bPendingIO)
  231. {
  232. // 获取Overlapped结果;
  233. if( GetOverlappedResult(hPipe, &pIoContext->m_Overlapped, &dwTransBytes, TRUE) == FALSE)
  234. {
  235. printf("ConnectNamedPipe failed %d\n",GetLastError());
  236. return FALSE;
  237. }
  238. }
  239. break;
  240. // 读写完成;
  241. case WAIT_IO_COMPLETION:
  242. break;
  243. }
  244. return TRUE;
  245. }
  246. BOOL CPipeClient::SendMessage(PACKAGE &pak)
  247. {
  248. // 是否连接了服务端;
  249. if ( m_hPipeInst == INVALID_HANDLE_VALUE )
  250. return FALSE;
  251. // 是否初始化了句柄;
  252. return FALSE;
  253. }
  254. BOOL CPipeClient::SendData(const TCHAR *lpszMsg, DWORD dwDataLen)
  255. {
  256. if ( m_hPipeInst == INVALID_HANDLE_VALUE )
  257. return FALSE;
  258. static int i = 0;
  259. DWORD dwNumberOfBytesWritten = 0;
  260. char szMsg[255] = {0};//"你好----001";
  261. sprintf(szMsg, "发送内容00000000000000000000000000000000000000000000000000000000000000000000000000000000000000:%d,%d", ::GetCurrentProcessId(), i++);
  262. BOOL fWrite = WriteFile(m_hPipeInst,szMsg,strlen(szMsg),&dwNumberOfBytesWritten, NULL);//;&m_IoWrite.m_Overlapped);
  263. //WaitFinish(m_hPipeInst, &m_IoWrite);
  264. if ( fWrite )
  265. {
  266. Utility::dprintf(_T("SendData:%s\n"),szMsg);
  267. }
  268. return TRUE;
  269. }