Эх сурвалжийг харах

服务端WriteFile时使用重叠IO,加快服务端的响应速度。同时,每个ReadIO关联一个WriteIO.

JeffWang 3 жил өмнө
parent
commit
bf4688eadd

+ 2 - 2
Source/OGCAssistTool/OGCAssistTool/OGCAssistTool.cpp

@@ -128,6 +128,8 @@ BOOL COGCAssistToolApp::InitInstance()
 
 	MTVERIFY(GLOBAL::GetConfigInfo());
 
+	GLOBAL::g_IOCP.Start();
+
 #pragma region ´ò¿ªÄ¿±ê½ø³Ì;
 	if ( StartOGCTool() < 0 )
 		return FALSE;
@@ -141,8 +143,6 @@ BOOL COGCAssistToolApp::InitInstance()
 	}
 #pragma endregion
 
-	GLOBAL::g_IOCP.Start();
-
 	COGCAssistToolDlg dlg;
 	m_pMainWnd = &dlg;
 	INT_PTR nResponse = dlg.DoModal();

+ 36 - 9
Source/OGCAssistTool/OGCAssistTool/PipeService.cpp

@@ -69,6 +69,7 @@ DWORD WINAPI CIOCPPipe::_WorkerThread(LPVOID lpParam)
 		if ( EXIT_CODE==(DWORD)pPipeContext )
 		{
 			//break;
+			dprintf(_T("IOCP: 退出消息"));
             continue;
 		}
 
@@ -91,6 +92,7 @@ DWORD WINAPI CIOCPPipe::_WorkerThread(LPVOID lpParam)
 			// 读取传入的参数
 			PER_IO_CONTEXT* pIoContext = CONTAINING_RECORD(pOverlapped, PER_IO_CONTEXT, m_Overlapped);  
 
+			dprintf(_T("IOCP: 读取传入的参数=%ld"), pIoContext->m_OpType);
 			// 判断是否有客户端断开了
 			if((0 == dwBytesTransfered) && ( OP_RECV==pIoContext->m_OpType || OP_SEND==pIoContext->m_OpType))  
 			{  
@@ -109,9 +111,10 @@ DWORD WINAPI CIOCPPipe::_WorkerThread(LPVOID lpParam)
 				switch( pIoContext->m_OpType )  
 				{  
 				case OP_ACCEPT:
-					{ 
+					{
+						dprintf(_T("客户端连接成功"));
 						pIOCPModel->DoAccpet( pPipeContext, pIoContext );
-                        dprintf(_T("客户端连接成功"));
+                        
 						// 发送第一个请求:回调处理;
 						if ( lpOnConnectCallback )
 						{
@@ -121,14 +124,19 @@ DWORD WINAPI CIOCPPipe::_WorkerThread(LPVOID lpParam)
 					break;
 				case OP_RECV:
 					{
+						dprintf(_T("客户端消息到达"));
 						pIOCPModel->DoRecv( pPipeContext, pIoContext );
 					}
 					break;
 				case OP_SEND:
+					{
+						// 发送成功后,此处有消息到达;
+						dprintf(_T("消息送达客户端"));
+					}
 					break;
 				default:
 					// 不应该执行到这里
-					TRACE(_T("_WorkThread中的 pIoContext->m_OpType 参数异常.\n"));
+					dprintf(_T("_WorkThread中的 pIoContext->m_OpType 参数异常.\n"));
 					break;
 				}
 			}
@@ -320,6 +328,8 @@ bool CIOCPPipe::PostAccept()
 
 	return fPendingIO;
 #else
+
+	dprintf(_T("Post Accept <%lp> 成功!"), &pNewIoContext->m_Overlapped); 
 	AddToContextList(pPipeContext);
 
 	return true;
@@ -352,7 +362,7 @@ bool CIOCPPipe::PostRecv( PER_IO_CONTEXT* pIoContext )
 
 	dprintf(_T("等待客户端消息"));
 	// 初始化完成后,投递WSARecv请求
-	int nBytesRecv = ReadFile( pIoContext->m_PipeAccept, pIoContext->chRequest, BUFSIZE, &dwBytes, p_ol );
+	int nBytesRecv = ReadFile( pIoContext->m_PipeAccept, pIoContext->szBuffer, BUFSIZE, &dwBytes, p_ol );
 
 	// 如果返回值错误,并且错误的代码并非是Pending的话,那就说明这个重叠请求失败了
 	if ((-1 == nBytesRecv) && (ERROR_IO_PENDING != GetLastError()))
@@ -457,8 +467,8 @@ void CIOCPPipe::RecvProcess(PER_PIPE_CONTEXT* pPipeContext, PER_IO_CONTEXT* pIoC
 		*/
 		DATAHEADER header;
 		MSG_INFO msg_info;
-		memcpy(&header, pIoContext->chRequest, sizeof(DATAHEADER));
-		memcpy(&msg_info, pIoContext->chRequest+sizeof(DATAHEADER), sizeof(MSG_INFO));
+		memcpy(&header, pIoContext->szBuffer, sizeof(DATAHEADER));
+		memcpy(&msg_info, pIoContext->szBuffer+sizeof(DATAHEADER), sizeof(MSG_INFO));
 
 		dprintf(_T("接收到客户端消息:Result=%d, Tpye=%d, Proctocl=%d, Len=%ld, Name=%s, Id=%ld, Data=%s"), 
 			msg_info.byResult,
@@ -473,12 +483,27 @@ void CIOCPPipe::RecvProcess(PER_PIPE_CONTEXT* pPipeContext, PER_IO_CONTEXT* pIoC
 		DWORD lpNumberOfBytesWritten = 0;
 		TCHAR szMsg[MAX_PATH] = {0};
 		_stprintf(szMsg, _T("%ld:%ld"), GetCurrentThreadId(), GetTickCount());
+#if 0
 		// WriteFile时,不需要异步处理,所以重叠IO参数NUULL;
-		BOOL bRet = WriteFile(pIoContext->m_PipeAccept, pIoContext->chRequest, pIoContext->m_Overlapped.InternalHigh, &lpNumberOfBytesWritten, NULL);
+		BOOL bRet = WriteFile(pIoContext->m_PipeAccept, pIoContext->szBuffer, pIoContext->m_Overlapped.InternalHigh, &lpNumberOfBytesWritten, NULL);
 		if ( !bRet )
 		{
-			dprintf(_T("发送消息失败:%s, %ld, %ld"), pIoContext->chRequest, GetLastError(), GetCurrentThreadId());
+			dprintf(_T("发送消息失败:%s, %ld, %ld"), pIoContext->szBuffer, GetLastError(), GetCurrentThreadId());
 		}
+#else
+		if ( pIoContext->pWriteIoContext == NULL )
+		{
+			pIoContext->pWriteIoContext = new PER_IO_CONTEXT();
+			pIoContext->pWriteIoContext->m_OpType = OP_SEND;
+			pIoContext->pWriteIoContext->m_PipeAccept = pIoContext->m_PipeAccept;
+		}
+		memcpy(pIoContext->pWriteIoContext->szBuffer, pIoContext->szBuffer, pIoContext->m_Overlapped.InternalHigh);
+		BOOL bRet = WriteFile(pIoContext->m_PipeAccept, pIoContext->pWriteIoContext->szBuffer, pIoContext->m_Overlapped.InternalHigh, &lpNumberOfBytesWritten, &pIoContext->pWriteIoContext->m_Overlapped);
+		if ( !bRet )
+		{
+			dprintf(_T("发送消息失败:%s, %ld, %ld"), pIoContext->szBuffer, GetLastError(), GetCurrentThreadId());
+		}
+#endif
 	}
 }
 
@@ -492,6 +517,7 @@ bool CIOCPPipe::HandleError( PER_PIPE_CONTEXT *pPipeContext, const DWORD& dwErr
 	// 如果是超时了,就再继续等吧  
 	if( WAIT_TIMEOUT == dwErr )  
 	{  	
+		dprintf(_T("HandleError: 超时"));
 		return true;
 	}
 	// 可能是客户端异常退出了
@@ -499,10 +525,11 @@ bool CIOCPPipe::HandleError( PER_PIPE_CONTEXT *pPipeContext, const DWORD& dwErr
 	{
 		RemoveContext(pPipeContext);
 		//ShowMessage( _T("检测到客户端异常退出!") );
-		dprintf(_T("检测到客户端异常退出"));
+		dprintf(_T("检测到客户端异常退出\n\n"));
 		return true;
 	}
 
+	dprintf(_T("完成端口操作出现错误,线程退出。错误代码:%d"),dwErr);
 	ShowMessage( _T("完成端口操作出现错误,线程退出。错误代码:%d"),dwErr );
 
 	return false;

+ 21 - 12
Source/OGCAssistTool/OGCAssistTool/PipeService.h

@@ -24,26 +24,29 @@ typedef struct _PER_IO_CONTEXT
     HANDLE m_PipeAccept;
     OPERATION_TYPE m_OpType;
 	// 接收客户端的消息;
-    TCHAR chRequest[BUFSIZE];
-    DWORD cbRead;
+    TCHAR szBuffer[BUFSIZE];
+    DWORD dwBufferLine;
 	// 发送给客户的消息;
-    TCHAR chReply[BUFSIZE];
-    DWORD cbToWrite;
+    //TCHAR chReply[BUFSIZE];
+    //DWORD cbToWrite;
     // 管道状态;
-    DWORD dwState;
+    //DWORD dwState;
     // IO是否在等待;
-    BOOL fPendingIO;
+    //BOOL fPendingIO;
+	// 创建写IO;
+	_PER_IO_CONTEXT *pWriteIoContext;
     
     // 初始化
     _PER_IO_CONTEXT()
     {
         ZeroMemory(&m_Overlapped, sizeof(m_Overlapped));
-        ZeroMemory(chRequest, BUFSIZE);
-        ZeroMemory(chReply, BUFSIZE);
+        ZeroMemory(szBuffer, BUFSIZE);
+        //ZeroMemory(chReply, BUFSIZE);
 		m_PipeAccept = INVALID_HANDLE_VALUE;
         m_OpType = OP_ACCEPT;
-        fPendingIO = FALSE;
-        dwState = 0;
+		pWriteIoContext = NULL;
+        //fPendingIO = FALSE;
+        //dwState = 0;
     }
 
     // 释放掉句柄
@@ -54,14 +57,18 @@ typedef struct _PER_IO_CONTEXT
             //CloseHandle(m_PipeAccept);// 此处不能CloseHandle,因为m_PipeAccept在PER_PIPE_CONTEXT中已释放;
             m_PipeAccept = INVALID_HANDLE_VALUE;
         }
+
+		if ( pWriteIoContext )
+			delete pWriteIoContext;
+		pWriteIoContext = NULL;
     }
 
     // 重置缓冲区内容
     void ResetBuffer()
     {
 		dprintf(_T("ResetBuffer:%p"), &m_Overlapped);
-        ZeroMemory(chRequest, BUFSIZE);
-        ZeroMemory(chReply, BUFSIZE);
+        ZeroMemory(szBuffer, BUFSIZE);
+        //ZeroMemory(chReply, BUFSIZE);
     }
 
 } PER_IO_CONTEXT, *PPER_IO_CONTEXT;
@@ -124,6 +131,8 @@ typedef struct _PER_PIPE_CONTEXT
 		{
 			if( pContext == m_arrayIoContext.GetAt(i) )
 			{
+				if ( pContext->pWriteIoContext )
+					delete pContext->pWriteIoContext;
 				delete pContext;
 				pContext = NULL;
 				m_arrayIoContext.RemoveAt(i);				

+ 4 - 2
Source/OGCAssistTool/OGCAssistTool/stdafx.cpp

@@ -14,9 +14,11 @@ void dprintf(TCHAR* pszStr, ...)
 	struct tm gmtm = { 0 };
 	localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
 #if _MSC_VER >= 1200 && _MSC_VER < 1500
-	sprintf(szData, _T("%s %s "), _T("[Assist-Server] "), gmtm.tm_year + 1900, gmtm.tm_mon + 1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec);
+	sprintf(szData, _T("%s %s "), _T("[Assist-Server] %ld "), 
+		gmtm.tm_year + 1900, gmtm.tm_mon + 1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec, GetCurrentThreadId());
 #else
-	_stprintf_s(szData, _T("%s %04d-%02d-%02d %02d:%02d:%02d "), _T("[Assist-Server] "), gmtm.tm_year + 1900, gmtm.tm_mon + 1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec);
+	//_stprintf_s(szData, _T("%s %04d-%02d-%02d %02d:%02d:%02d "), _T("[Assist-Server] "), gmtm.tm_year + 1900, gmtm.tm_mon + 1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec);
+	_stprintf_s(szData, _T("%s %02d:%02d:%02d <%ld>"), _T("[Assist-Server] "), gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec, GetCurrentThreadId());
 #endif
 	int len = _tcslen(szData);//_tcslen已获取的是字节数,不需要*sizeof(TCHAR)
 	va_list args;