123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- #include "StdAfx.h"
- #include "PipeClient.h"
- #include "Utility.h"
- std::string CPipeClient::m_LastData;
- PER_IO_CONTEXT CPipeClient::m_IoRead;
- PER_IO_CONTEXT CPipeClient::m_IoWrite;
- CPipeClient::CPipeClient(LPCTSTR lpPipeName, DWORD dwMode)
- {
- m_hPipeInst = INVALID_HANDLE_VALUE;
- m_bClientStop = FALSE;
- m_dwMode = dwMode;
- memset(m_szPipeName, 0, MAX_PATH*sizeof(TCHAR));
- if ( lpPipeName )
- _stprintf_s(m_szPipeName, _T("%s"), lpPipeName);
- }
- CPipeClient::~CPipeClient(void)
- {
- StopWork();
- if ( m_hPipeInst != INVALID_HANDLE_VALUE )
- CloseHandle(m_hPipeInst);
- }
- BOOL CPipeClient::StartWork()
- {
- if ( !m_bClientStop )
- {
- BOOL bRet = TRUE;
- HANDLE hConnect = CreateThread(NULL, 0, ConnectThread, this, 0, NULL);
- HANDLE hReadMsg = CreateThread(NULL, 0, ReadMsgThread, this, 0, NULL);
- if ( hConnect == NULL || hReadMsg == NULL )
- bRet = FALSE;
- if ( hConnect )
- CloseHandle(hConnect);
- if ( hReadMsg )
- CloseHandle(hReadMsg);
- return bRet;
- }
- return TRUE;
- }
- DWORD CPipeClient::ConnectThread(LPVOID lpParam)
- {
- CPipeClient *pInstance = (CPipeClient*)lpParam;
- if ( !pInstance )
- return 0L;
- while(!pInstance->m_bClientStop)
- {
- if ( pInstance->m_hPipeInst != INVALID_HANDLE_VALUE ) {
- // 1分钟检测;
- Sleep(60000);
- Utility::dprintf(_T("m_hPipeInst 已存在\n"));
- continue;
- }
- // 等待10秒;
- if ( !WaitNamedPipe(pInstance->m_szPipeName, 10000) )
- {// 如果管道不存在,会立即返回而不考虑超时值,所以此处仍要Sleep;
- Utility::dprintf(_T("<%ld> WaitNamedPipe 失败\n"), Utility::g_WndInfo.dwProcessId);
- Sleep(10000);
- continue;
- }
- pInstance->m_hPipeInst = CreateFile(
- pInstance->m_szPipeName, // pipe name
- GENERIC_READ | GENERIC_WRITE, // read and write access
- 0, // no sharing
- NULL, // default security attributes
- OPEN_EXISTING, // opens existing pipe
- FILE_FLAG_OVERLAPPED, // default attributes
- NULL); // no template file
- // 创建成功,退出;
- if ( pInstance->m_hPipeInst != INVALID_HANDLE_VALUE )
- {
- // 管道连接成功,修改管道通信模式:message-read mode.
- BOOL fSuccess = SetNamedPipeHandleState(
- pInstance->m_hPipeInst, // pipe handle
- &pInstance->m_dwMode, // new pipe mode
- NULL, // don't set maximum bytes
- NULL); // don't set maximum time
- if (!fSuccess) {
- Utility::dprintf(_T("SetNamedPipeHandleState failed. GLE=%d\n"), GetLastError() );
- CloseHandle(pInstance->m_hPipeInst);
- pInstance->m_hPipeInst = INVALID_HANDLE_VALUE;
- }
- }
- else
- {
- // Exit if an error other than ERROR_PIPE_BUSY occurs.
- if ( GetLastError() != ERROR_PIPE_BUSY )
- {
- Utility::dprintf(_T("Could not open pipe. GLE=%d\n"), GetLastError() );
- }
- }
- }
- Utility::dprintf(_T("<%ld> ConnectThread 退出\n"), Utility::g_WndInfo.dwProcessId);
- return 0;
- }
- DWORD CPipeClient::ReadMsgThread(LPVOID lpParam)
- {
- CPipeClient *pInstance = (CPipeClient*)lpParam;
- if ( !pInstance )
- return 0L;
- int i = 0;
- DWORD dwError = 0;
- BOOL bSuccess = FALSE;
- while(!pInstance->m_bClientStop)
- {
- if ( pInstance->m_hPipeInst == INVALID_HANDLE_VALUE ) {
- Sleep(5000);
- continue;
- }
- #if 1 // 分配足够大的缓冲,保证C/S两端通信内容不超过该大小;
- bSuccess = ReadFile(pInstance->m_hPipeInst, m_IoRead.szBuffer, BUFSIZE, &m_IoRead.dwBufferSize, (OVERLAPPED*)&pInstance->m_IoRead);
- if ( bSuccess )
- {
- // 打印结果;
- Utility::dprintf(_T("读取数据:Error=%ld, Len=%ld, Data=%s\n"), dwError, m_IoRead.m_Overlapped.InternalHigh, m_IoRead.szBuffer);
- // 处理结果;
- }
- else
- {
- // 等待完成;
- if ( !WaitFinish(pInstance->m_hPipeInst, &m_IoRead) )
- {
- // 出现错误;
- Utility::dprintf("CloseHandle\n");
- CloseHandle(pInstance->m_hPipeInst);
- pInstance->m_hPipeInst = INVALID_HANDLE_VALUE;
- }
- else
- {
- // 打印结果;
- Utility::dprintf(_T("读取数据:Error=%ld, Len=%ld, Data=%s\n"), dwError, m_IoRead.m_Overlapped.InternalHigh, m_IoRead.szBuffer);
- // 处理结果;
- }
- }
- // 重置Buffer;
- memset(m_IoRead.szBuffer, 0, BUFSIZE);
- #else // 分配的缓冲区,不足以一次性存储C/S两端的通信内容时;
- do
- {
- bSuccess = ReadFile(pInstance->m_hPipeInst, m_IoRead.szBuffer, BUFSIZE, &m_IoRead.dwBufferSize, (OVERLAPPED*)&pInstance->m_IoRead);
- if ( bSuccess )
- {
- // 打印结果;
- dwError = GetLastError();// 此时bSuccess为True,但GetLastError仍为ERROR_MORE_DATA属于正常现象;
- m_LastData.append((char*)m_IoRead.szBuffer, m_IoRead.m_Overlapped.InternalHigh);
- // 处理结果;
- }
- else
- {
- dwError = GetLastError();
- if ( dwError == ERROR_MORE_DATA )
- {// 如果立即返回,没有IO PENDING;
- // 将当前数据保存;
- m_LastData.append((char*)m_IoRead.szBuffer, m_IoRead.m_Overlapped.InternalHigh);
- }
- else if ( dwError == ERROR_IO_PENDING )
- {
- DWORD dwWait = -1;
- DWORD dwTransBytes = -1;
- // 等待读写操作完成;
- dwWait = WaitForSingleObject(m_IoRead.m_Overlapped.hEvent,INFINITE);
- switch(dwWait)
- {
- case 0:
- // 获取Overlapped结果;
- if( GetOverlappedResult(pInstance->m_hPipeInst, &m_IoRead.m_Overlapped, &dwTransBytes, TRUE) == FALSE)
- {
- dwError = GetLastError();
- if ( dwError == ERROR_MORE_DATA )
- {
- m_LastData.append((char*)m_IoRead.szBuffer, m_IoRead.m_Overlapped.InternalHigh);
- }
- else
- {
- Utility::dprintf(_T("GetOverlappedResult:Error=%ld"), dwError);
- }
- }
- else
- {
- bSuccess = TRUE;
- Utility::dprintf(_T("GetOverlappedResult:Error=%ld"), GetLastError());
- m_LastData.append((char*)m_IoRead.szBuffer, m_IoRead.m_Overlapped.InternalHigh);
- }
- break;
- // 读写完成;
- case WAIT_IO_COMPLETION:
- break;
- }
- }
- else if ( dwError == ERROR_PIPE_CONNECTED )
- {// 管道的另一端有一个过程;
- DWORD dwWait = -1;
- DWORD dwTransBytes = -1;
- SetEvent(m_IoRead.m_Overlapped.hEvent);
- Utility::dprintf(_T("管道的另一端有一个过程:ERROR_PIPE_CONNECTED\n"));
- dwWait = WaitForSingleObject(m_IoRead.m_Overlapped.hEvent,INFINITE);
- }
- }
- // 清空缓存数据;
- memset(m_IoRead.szBuffer, 0, BUFSIZE);
- } while ( !bSuccess ); // repeat loop if ERROR_MORE_DATA
-
- Utility::dprintf(_T("读取数据:Error=%ld, Len=%ld, Data=%s\n"), dwError, m_LastData.size(), m_LastData.data());
- m_LastData.clear();
- #endif
- }
- Utility::dprintf(_T("<%ld> ReadMsgThread 退出\n"),Utility::g_WndInfo.dwProcessId);
- return 0;
- }
- BOOL CPipeClient::WaitFinish(HANDLE hPipe, PER_IO_CONTEXT *pIoContext)
- {
- bool bPendingIO = false;
- switch(GetLastError())
- {
- // 正在连接中;
- case ERROR_IO_PENDING:
- bPendingIO = true;
- break;
- case ERROR_MORE_DATA:
- break;
- // 已经连接;
- case ERROR_PIPE_CONNECTED:
- SetEvent(pIoContext->m_Overlapped.hEvent);
- break;
- }
- DWORD dwWait = -1;
- DWORD dwTransBytes = -1;
- // 等待读写操作完成;
- dwWait = WaitForSingleObject(pIoContext->m_Overlapped.hEvent,INFINITE);
- switch(dwWait)
- {
- case 0:
- if (bPendingIO)
- {
- // 获取Overlapped结果;
- if( GetOverlappedResult(hPipe, &pIoContext->m_Overlapped, &dwTransBytes, TRUE) == FALSE)
- {
- printf("ConnectNamedPipe failed %d\n",GetLastError());
- return FALSE;
- }
- }
- break;
- // 读写完成;
- case WAIT_IO_COMPLETION:
- break;
- }
- return TRUE;
- }
- BOOL CPipeClient::SendMessage(PACKAGE &pak)
- {
- // 是否连接了服务端;
- if ( m_hPipeInst == INVALID_HANDLE_VALUE )
- return FALSE;
- // 是否初始化了句柄;
- return FALSE;
- }
- BOOL CPipeClient::SendData(const TCHAR *lpszMsg, DWORD dwDataLen)
- {
- if ( m_hPipeInst == INVALID_HANDLE_VALUE )
- return FALSE;
- static int i = 0;
- DWORD dwNumberOfBytesWritten = 0;
- char szMsg[255] = {0};//"你好----001";
- sprintf(szMsg, "发送内容00000000000000000000000000000000000000000000000000000000000000000000000000000000000000:%d,%d", ::GetCurrentProcessId(), i++);
- BOOL fWrite = WriteFile(m_hPipeInst,szMsg,strlen(szMsg),&dwNumberOfBytesWritten, NULL);//;&m_IoWrite.m_Overlapped);
- //WaitFinish(m_hPipeInst, &m_IoWrite);
- if ( fWrite )
- {
- Utility::dprintf(_T("SendData:%s\n"),szMsg);
- }
- return TRUE;
- }
|