Explorar o código

添加回调函数;同时,服务端WriteFile时不需要使用异步,重叠IO参数置为NULL。如果WriteFile也要重叠IO,结构需要变化:要为WriteFile创建新的PER_IO_CONTEXT。

Jeff %!s(int64=3) %!d(string=hai) anos
pai
achega
ab7f5e0257

+ 13 - 1
Source/OGCAssistTool/OGCAssistTool/PipeService.cpp

@@ -21,6 +21,9 @@
 // 释放Socket宏
 #define RELEASE_SOCKET(x)               {if(x !=INVALID_SOCKET) { closesocket(x);x=INVALID_SOCKET;}}
 
+OnConnectCallback CIOCPPipe::lpOnConnectCallback = NULL;
+OnDisconnectCallback CIOCPPipe::lpOnDisconnectCallback = NULL;
+OnReciveCallback CIOCPPipe::lpOnReciveCallback = NULL;
 
 CIOCPPipe::CIOCPPipe(void)
 {
@@ -92,7 +95,10 @@ DWORD WINAPI CIOCPPipe::_WorkerThread(LPVOID lpParam)
 			if((0 == dwBytesTransfered) && ( OP_RECV==pIoContext->m_OpType || OP_SEND==pIoContext->m_OpType))  
 			{  
 				//pIOCPModel->_ShowMessage( _T("客户端 %s:%d 断开连接."),pIoContext->szClientName, pIoContext->dwProcessId );
-
+				if ( lpOnDisconnectCallback )
+				{
+					lpOnDisconnectCallback(pIoContext);
+				}
 				// 释放掉对应的资源
 				pIOCPModel->RemoveContext( pPipeContext );
 
@@ -106,6 +112,11 @@ DWORD WINAPI CIOCPPipe::_WorkerThread(LPVOID lpParam)
 					{ 
 						pIOCPModel->DoAccpet( pPipeContext, pIoContext );
                         dprintf(_T("客户端连接成功"));
+						// 发送第一个请求:回调处理;
+						if ( lpOnConnectCallback )
+						{
+							lpOnConnectCallback(pIoContext);
+						}
 					}
 					break;
 				case OP_RECV:
@@ -451,6 +462,7 @@ 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());
+		// WriteFile时,不需要异步处理,所以重叠IO参数NUULL;
 		BOOL bRet = WriteFile(pIoContext->m_PipeAccept, pIoContext->chRequest, pIoContext->m_Overlapped.InternalHigh, &lpNumberOfBytesWritten, NULL);
 		if ( !bRet )
 		{

+ 20 - 26
Source/OGCAssistTool/OGCAssistTool/PipeService.h

@@ -58,14 +58,12 @@ typedef struct _PER_IO_CONTEXT
     // 重置缓冲区内容
     void ResetBuffer()
     {
-		dprintf(_T("ResetBuffer\n"));
         ZeroMemory(chRequest, BUFSIZE);
         ZeroMemory(chReply, BUFSIZE);
     }
 
 } PER_IO_CONTEXT, *PPER_IO_CONTEXT;
 
-
 typedef struct _PER_PIPE_CONTEXT
 {
 	HANDLE m_hPipe;
@@ -133,6 +131,12 @@ typedef struct _PER_PIPE_CONTEXT
 	}
 }PER_PIPE_CONTEXT, *PPER_PIPE_CONTEXT;
 
+// 回调客户端接入时;
+typedef BOOL(CALLBACK *OnConnectCallback)(PER_IO_CONTEXT* pIoContext);
+// 回调客户端断开时;
+typedef BOOL(CALLBACK* OnDisconnectCallback)(PER_IO_CONTEXT* pIoContext);
+// 回调客户端消息到来时;
+typedef BOOL(CALLBACK *OnReciveCallback)(PER_PIPE_CONTEXT *pPipeContext, PPER_IO_CONTEXT *pIoContext);
 
 // 工作者线程的线程参数
 class CIOCPPipe;
@@ -154,77 +158,67 @@ public:
 public:
     // 启动服务器
     bool Start();
-
     //	停止服务器
     void Stop();
-
     // 设置主界面的指针,用于调用显示信息到界面中
     void SetMainDlg(CDialog *p) { m_pMain = p; }
-
 	// 向客户端发送消息;
 	bool SendMessage();
+	// SetCallback;
+	static void SetCallBack(LPVOID lpOnConnect, LPVOID lpOnDisconnect, LPVOID lpOnRecive)
+	{
+		if ( lpOnConnectCallback == NULL )
+			lpOnConnectCallback = (OnConnectCallback)lpOnConnect;
+
+		if ( lpOnDisconnectCallback == NULL )
+			lpOnDisconnectCallback = (OnDisconnectCallback)lpOnDisconnect;
 
+		if ( lpOnReciveCallback == NULL )
+			lpOnReciveCallback = (OnReciveCallback)lpOnRecive;
+	}
 protected:
     // 初始化IOCP
     bool InitIOCP();
-
     // 最后释放资源
     void DeInitialize();
-
     // 投递Accept请求
     bool PostAccept();
-
     // 投递接收数据请求
     bool PostRecv(PER_IO_CONTEXT *pIoContext);
-
     // 在有客户端连入的时候,进行处理
     bool DoAccpet(PER_PIPE_CONTEXT *pPipeContext, PER_IO_CONTEXT *pIoContext);
-
     // 在有接收的数据到达的时候,进行处理
     bool DoRecv(PER_PIPE_CONTEXT *pPipeContext, PER_IO_CONTEXT *pIoContext);
-
     // 将客户端的相关信息存储到数组中
     void AddToContextList(PER_PIPE_CONTEXT *pPipeContext);
-
     // 将客户端的信息从数组中移除
     void RemoveContext(PER_PIPE_CONTEXT *pPipeContext);
-
     // 清空客户端信息
     void ClearContextList();
-
     // 将句柄绑定到完成端口中
     bool AssociateWithIOCP(PER_IO_CONTEXT *pIoContext);
-
     // 处理完成端口上的错误
     bool HandleError(PER_PIPE_CONTEXT *pPipeContext, const DWORD &dwErr);
-
     // 线程函数,为IOCP请求服务的工作者线程
     static DWORD WINAPI _WorkerThread(LPVOID lpParam);
-
     // 获得本机的处理器数量
     int GetNoOfProcessors();
-
     // 判断客户端Socket是否已经断开
     bool IsSocketAlive(SOCKET s);
-
     // 在主界面中显示信息
     void ShowMessage(const CString szFormat, ...) const;
-
 	// 处理返回值;
 	void RecvProcess(PER_PIPE_CONTEXT* pPipeContext, PER_IO_CONTEXT* pIoContext);
 
 private:
+	static OnConnectCallback lpOnConnectCallback;
+	static OnDisconnectCallback lpOnDisconnectCallback;
+	static OnReciveCallback lpOnReciveCallback;
     HANDLE m_hShutdownEvent; // 用来通知线程系统退出的事件,为了能够更好的退出线程
-
     HANDLE m_hIOCompletionPort; // 完成端口的句柄
-
     HANDLE *m_phWorkerThreads; // 工作者线程的句柄指针
-
     int m_nThreads; // 生成的线程数量
-
     CDialog *m_pMain; // 主界面的界面指针,用于在主界面中显示消息
-
     CRITICAL_SECTION m_csContextList; // 用于Worker线程同步的互斥量
-
     CArray<PER_PIPE_CONTEXT *> m_arrayClientContext; // 客户端Socket的Context信息
 };