1. 首页
  2. 编程语言
  3. C++ 
  4. IOCP 完成端口模型 源码示例

IOCP 完成端口模型 源码示例

上传者: 2019-04-08 20:00:18上传 ZIP文件 159.78KB 热度 49次
IOCP 完成端口模型 源码示例 // MyIOCP.cpp: implementation of the MyIOCP class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "iocp.h" #include "MyIOCP.h" #include ".\myiocp.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #de fine new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// MyIOCP::MyIOCP() { m_bFlood=FALSE; m_sSendText=""; m_iNumberOfMsg=0; } MyIOCP::~MyIOCP() { } void MyIOCP::NotifyReceivedPackage(CIOCPBuffer *pOverlapBuff,int nSize,ClientContext *pContext) { BYTE PackageType=pOverlapBuff->GetPackageType(); switch (PackageType) { case Job_SendText2Client : Packagetext(pOverlapBuff,nSize,pContext); break; case Job_SendFileInfo : PackageFileTransfer(pOverlapBuff,nSize,pContext); break; case Job_StartFileTransfer: PackageStartFileTransfer(pOverlapBuff,nSize,pContext); break; case Job_AbortFileTransfer: #ifdef TRANSFERFILEFUNCTIONALITY DisableSendFile(pContext->m_Socket); #endif break; }; } /* * This functions defines what should be done when A job from the work queue is arrived. * (not used). * */ void MyIOCP::ProcessJob(JobItem *pJob,IOCPS* pServer) { switch (pJob->m_command) { case Job_SendText2Client : break; } } void MyIOCP::AppendLog(CString msg) { TRACE("%s\r\n",msg); int nLen = msg.GetLength(); char *pBuffer = new char[nLen+1]; strcpy(pBuffer,(const char*)msg); pBuffer[nLen]='\0'; BOOL bRet=::PostMessage(m_hWnd, WM_LOGG_APPEND, 0, (LPARAM) pBuffer); } void MyIOCP::NotifyNewConnection(ClientContext *pcontext) { unsigned int *pBuffer= new unsigned int; if(pBuffer) *pBuffer=pcontext->m_Socket; ::PostMessage(m_hWnd, WM_NEW_CONNECTION, 0, (LPARAM) pBuffer); } void MyIOCP::NotifyDisconnectedClient(ClientContext *pContext) { unsigned int *pBuffer= new unsigned int; if(pBuffer) *pBuffer=pContext->m_Socket; ::PostMessage(m_hWnd, WM_CLIENTDISCONNECTED, 0, (LPARAM) pBuffer); } void MyIOCP::NotifyNewClientContext(ClientContext *pContext) { pContext->m_iNumberOfReceivedMsg=0; pContext->m_bUpdate=FALSE; } // Text in a Package is arrived. void MyIOCP::Packagetext(CIOCPBuffer *pOverlapBuff,int nSize,ClientContext *pContext) { CString txt=""; BYTE type; if(pOverlapBuff->GetPackageInfo(type,txt)) { // to be sure that pcontext Suddenly does not dissapear by disconnection... m_ContextMapLock.Lock(); pContext->m_ContextLock.Lock(); pContext->m_sReceived=txt; // Update that we have data pContext->m_iNumberOfReceivedMsg++; pContext->m_bUpdate=TRUE; pContext->m_ContextLock.Unlock(); m_ContextMapLock.Unlock(); // Update Statistics. m_StatusLock.Lock(); m_iNumberOfMsg++; m_StatusLock.Unlock(); // Send back the message if we are echoing. // Send Flood if needed. BOOL bRet=FALSE; if(m_bFlood) bRet=BuildPackageAndSend(pContext,m_sSendText); } } /* * This function is called when the remote connection, whant to send a file. * */ void MyIOCP::PackageFileTransfer(CIOCPBuffer *pOverlapBuff,int nSize,ClientContext *pContext) { #ifdef TRANSFERFILEFUNCTIONALITY CString sFileName=""; UINT iMaxFileSize=0; BYTE dummy=0; if(pOverlapBuff->GetPackageInfo(dummy,iMaxFileSize,sFileName)) { // Get The Current Path name and application name. CString sFilePath=""; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; CString strTemp; GetModuleFileName(NULL,strTemp.GetBuffer(MAX_PATH),MAX_PATH); strTemp.ReleaseBuffer(); _splitpath( strTemp, drive, dir, fname, ext ); sFilePath=drive; //Drive sFilePath+=dir; //dir sFilePath+=sFileName; //name.. TRACE("Incoming File >%s.\r\n",sFilePath); // Perpare for Receive if(PrepareReceiveFile(pContext->m_Socket,sFilePath,iMaxFileSize)) { // Send start file transfer.. CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(Job_StartFileTransfer)) ASend(pContext,pOverlapBuff); } }else { // Abort Transfer. CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(Job_AbortFileTransfer)) ASend(pContext,pOverlapBuff); } } // to be sure that pcontext Suddenly does not dissapear.. m_ContextMapLock.Lock(); pContext->m_ContextLock.Lock(); pContext->m_sReceived=sFilePath; // Update that we have data pContext->m_iNumberOfReceivedMsg++; pContext->m_ContextLock.Unlock(); m_ContextMapLock.Unlock(); // Update Statistics. m_StatusLock.Lock(); m_iNumberOfMsg++; m_StatusLock.Unlock(); } #endif } // The remote Connections whant to start the transfer. void MyIOCP::PackageStartFileTransfer(CIOCPBuffer *pOverlapBuff,int nSize,ClientContext *pContext) { #ifdef TRANSFERFILEFUNCTIONALITY StartSendFile(pContext->m_Socket); #endif } BOOL MyIOCP::BuildPackageAndSend(int ClientID, CString sText) { BOOL bRet=FALSE; m_ContextMapLock.Lock(); ClientContext* pContext = FindClient(ClientID); if (pContext == NULL) return FALSE; bRet=BuildPackageAndSend(pContext,sText); m_ContextMapLock.Unlock(); return bRet; } // Build the a text message message and send it.. BOOL MyIOCP::BuildPackageAndSend(ClientContext *pContext, CString sText) { CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(Job_SendText2Client,sText)) return ASend(pContext,pOverlapBuff); else { AppendLog("CreatePackage(0,sText) Failed in BuildPackageAndSend"); ReleaseBuffer(pOverlapBuff); return FALSE; } }else { CString msg; msg.Format("Could not allocate memory ASend: %s",ErrorCode2Text(WSAGetLastError())); AppendLog(msg); DisconnectClient(pContext->m_Socket); return FALSE; } return FALSE; } BOOL MyIOCP::BuildFilePackageAndSend(int ClientID,CString sFile) { BOOL bRet=FALSE; m_ContextMapLock.Lock(); ClientContext* pContext = FindClient(ClientID); if (pContext == NULL) return FALSE; bRet=BuildFilePackageAndSend(pContext,sFile); m_ContextMapLock.Unlock(); return bRet; } BOOL MyIOCP::BuildPackageAndSendToAll(CString sText) { CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(0,sText)) return ASendToAll(pOverlapBuff); else { AppendLog("CreatePackage(0,sText) Failed in BuildPackageAndSendToAll"); ReleaseBuffer(pOverlapBuff); return FALSE; } }else { CString msg; msg.Format("Could not allocate memory ASend: %s",ErrorCode2Text(WSAGetLastError())); AppendLog(msg); return FALSE; } return FALSE; } /* * Perpares for file transfer and sends a package containing information about the file. * */ BOOL MyIOCP::BuildFilePackageAndSend(ClientContext *pContext,CString sFile) { #ifdef TRANSFERFILEFUNCTIONALITY return PrepareSendFile(pContext->m_Socket,(LPCTSTR)sFile); #else return FALSE; #endif } BOOL MyIOCP::BuildStartFileTransferPackageAndSend(int ClientID) { BOOL bRet=FALSE; m_ContextMapLock.Lock(); ClientContext* pContext = FindClient(ClientID); if (pContext == NULL) return FALSE; bRet= BuildStartFileTransferPackageAndSend(pContext); m_ContextMapLock.Unlock(); return bRet; } /* * Send a "Start the file transfer package" to the remote connection. * * */ BOOL MyIOCP::BuildStartFileTransferPackageAndSend(ClientContext *pContext) { CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(Job_StartFileTransfer)) return ASend(pContext,pOverlapBuff); }else { CString msg; msg.Format("Could not allocate memory ASend: %s",ErrorCode2Text(WSAGetLastError())); AppendLog(msg); DisconnectClient(pContext->m_Socket); return FALSE; } return TRUE; } fine new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// MyIOCP::MyIOCP() { m_bFlood=FALSE; m_sSendText=""; m_iNumberOfMsg=0; } MyIOCP::~MyIOCP() { } void MyIOCP::NotifyReceivedPackage(CIOCPBuffer *pOverlapBuff,int nSize,ClientContext *pContext) { BYTE PackageType=pOverlapBuff->GetPackageType(); switch (PackageType) { case Job_SendText2Client : Packagetext(pOverlapBuff,nSize,pContext); break; case Job_SendFileInfo : PackageFileTransfer(pOverlapBuff,nSize,pContext); break; case Job_StartFileTransfer: PackageStartFileTransfer(pOverlapBuff,nSize,pContext); break; case Job_AbortFileTransfer: #ifdef TRANSFERFILEFUNCTIONALITY DisableSendFile(pContext->m_Socket); #endif break; }; } /* * This functions defines what should be done when A job from the work queue is arrived. * (not used). * */ void MyIOCP::ProcessJob(JobItem *pJob,IOCPS* pServer) { switch (pJob->m_command) { case Job_SendText2Client : break; } } void MyIOCP::AppendLog(CString msg) { TRACE("%s\r\n",msg); int nLen = msg.GetLength(); char *pBuffer = new char[nLen+1]; strcpy(pBuffer,(const char*)msg); pBuffer[nLen]='\0'; BOOL bRet=::PostMessage(m_hWnd, WM_LOGG_APPEND, 0, (LPARAM) pBuffer); } void MyIOCP::NotifyNewConnection(ClientContext *pcontext) { unsigned int *pBuffer= new unsigned int; if(pBuffer) *pBuffer=pcontext->m_Socket; ::PostMessage(m_hWnd, WM_NEW_CONNECTION, 0, (LPARAM) pBuffer); } void MyIOCP::NotifyDisconnectedClient(ClientContext *pContext) { unsigned int *pBuffer= new unsigned int; if(pBuffer) *pBuffer=pContext->m_Socket; ::PostMessage(m_hWnd, WM_CLIENTDISCONNECTED, 0, (LPARAM) pBuffer); } void MyIOCP::NotifyNewClientContext(ClientContext *pContext) { pContext->m_iNumberOfReceivedMsg=0; pContext->m_bUpdate=FALSE; } // Text in a Package is arrived. void MyIOCP::Packagetext(CIOCPBuffer *pOverlapBuff,int nSize,ClientContext *pContext) { CString txt=""; BYTE type; if(pOverlapBuff->GetPackageInfo(type,txt)) { // to be sure that pcontext Suddenly does not dissapear by disconnection... m_ContextMapLock.Lock(); pContext->m_ContextLock.Lock(); pContext->m_sReceived=txt; // Update that we have data pContext->m_iNumberOfReceivedMsg++; pContext->m_bUpdate=TRUE; pContext->m_ContextLock.Unlock(); m_ContextMapLock.Unlock(); // Update Statistics. m_StatusLock.Lock(); m_iNumberOfMsg++; m_StatusLock.Unlock(); // Send back the message if we are echoing. // Send Flood if needed. BOOL bRet=FALSE; if(m_bFlood) bRet=BuildPackageAndSend(pContext,m_sSendText); } } /* * This function is called when the remote connection, whant to send a file. * */ void MyIOCP::PackageFileTransfer(CIOCPBuffer *pOverlapBuff,int nSize,ClientContext *pContext) { #ifdef TRANSFERFILEFUNCTIONALITY CString sFileName=""; UINT iMaxFileSize=0; BYTE dummy=0; if(pOverlapBuff->GetPackageInfo(dummy,iMaxFileSize,sFileName)) { // Get The Current Path name and application name. CString sFilePath=""; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; CString strTemp; GetModuleFileName(NULL,strTemp.GetBuffer(MAX_PATH),MAX_PATH); strTemp.ReleaseBuffer(); _splitpath( strTemp, drive, dir, fname, ext ); sFilePath=drive; //Drive sFilePath+=dir; //dir sFilePath+=sFileName; //name.. TRACE("Incoming File >%s.\r\n",sFilePath); // Perpare for Receive if(PrepareReceiveFile(pContext->m_Socket,sFilePath,iMaxFileSize)) { // Send start file transfer.. CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(Job_StartFileTransfer)) ASend(pContext,pOverlapBuff); } }else { // Abort Transfer. CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(Job_AbortFileTransfer)) ASend(pContext,pOverlapBuff); } } // to be sure that pcontext Suddenly does not dissapear.. m_ContextMapLock.Lock(); pContext->m_ContextLock.Lock(); pContext->m_sReceived=sFilePath; // Update that we have data pContext->m_iNumberOfReceivedMsg++; pContext->m_ContextLock.Unlock(); m_ContextMapLock.Unlock(); // Update Statistics. m_StatusLock.Lock(); m_iNumberOfMsg++; m_StatusLock.Unlock(); } #endif } // The remote Connections whant to start the transfer. void MyIOCP::PackageStartFileTransfer(CIOCPBuffer *pOverlapBuff,int nSize,ClientContext *pContext) { #ifdef TRANSFERFILEFUNCTIONALITY StartSendFile(pContext->m_Socket); #endif } BOOL MyIOCP::BuildPackageAndSend(int ClientID, CString sText) { BOOL bRet=FALSE; m_ContextMapLock.Lock(); ClientContext* pContext = FindClient(ClientID); if (pContext == NULL) return FALSE; bRet=BuildPackageAndSend(pContext,sText); m_ContextMapLock.Unlock(); return bRet; } // Build the a text message message and send it.. BOOL MyIOCP::BuildPackageAndSend(ClientContext *pContext, CString sText) { CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(Job_SendText2Client,sText)) return ASend(pContext,pOverlapBuff); else { AppendLog("CreatePackage(0,sText) Failed in BuildPackageAndSend"); ReleaseBuffer(pOverlapBuff); return FALSE; } }else { CString msg; msg.Format("Could not allocate memory ASend: %s",ErrorCode2Text(WSAGetLastError())); AppendLog(msg); DisconnectClient(pContext->m_Socket); return FALSE; } return FALSE; } BOOL MyIOCP::BuildFilePackageAndSend(int ClientID,CString sFile) { BOOL bRet=FALSE; m_ContextMapLock.Lock(); ClientContext* pContext = FindClient(ClientID); if (pContext == NULL) return FALSE; bRet=BuildFilePackageAndSend(pContext,sFile); m_ContextMapLock.Unlock(); return bRet; } BOOL MyIOCP::BuildPackageAndSendToAll(CString sText) { CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(0,sText)) return ASendToAll(pOverlapBuff); else { AppendLog("CreatePackage(0,sText) Failed in BuildPackageAndSendToAll"); ReleaseBuffer(pOverlapBuff); return FALSE; } }else { CString msg; msg.Format("Could not allocate memory ASend: %s",ErrorCode2Text(WSAGetLastError())); AppendLog(msg); return FALSE; } return FALSE; } /* * Perpares for file transfer and sends a package containing information about the file. * */ BOOL MyIOCP::BuildFilePackageAndSend(ClientContext *pContext,CString sFile) { #ifdef TRANSFERFILEFUNCTIONALITY return PrepareSendFile(pContext->m_Socket,(LPCTSTR)sFile); #else return FALSE; #endif } BOOL MyIOCP::BuildStartFileTransferPackageAndSend(int ClientID) { BOOL bRet=FALSE; m_ContextMapLock.Lock(); ClientContext* pContext = FindClient(ClientID); if (pContext == NULL) return FALSE; bRet= BuildStartFileTransferPackageAndSend(pContext); m_ContextMapLock.Unlock(); return bRet; } /* * Send a "Start the file transfer package" to the remote connection. * * */ BOOL MyIOCP::BuildStartFileTransferPackageAndSend(ClientContext *pContext) { CIOCPBuffer *pOverlapBuff=AllocateBuffer(IOWrite); if(pOverlapBuff) { if(pOverlapBuff->CreatePackage(Job_StartFileTransfer)) return ASend(pContext,pOverlapBuff); }else { CString msg; msg.Format("Could not allocate memory ASend: %s",ErrorCode2Text(WSAGetLastError())); AppendLog(msg); DisconnectClient(pContext->m_Socket); return FALSE; } return TRUE; }
用户评论
码姐姐匿名网友 2019-04-08 20:00:18

不错,挺好的,是我想要的,谢谢

码姐姐匿名网友 2019-04-08 20:00:18

IOCP 下来看看

码姐姐匿名网友 2019-04-08 20:00:18

很好,学习了。

码姐姐匿名网友 2019-04-08 20:00:18

不错的资源。适合IOCP的学习

码姐姐匿名网友 2019-04-08 20:00:18

代码很不从,对我帮助很大,非常感谢无私分享

码姐姐匿名网友 2019-04-08 20:00:18

对完成端口的学习有很大帮助,可以好好学习学习了。

码姐姐匿名网友 2019-04-08 20:00:18

不错的例子,对我有点复杂

码姐姐匿名网友 2019-04-08 20:00:18

还不错,值得学习

码姐姐匿名网友 2019-04-08 20:00:18

很好,可以编译运行

码姐姐匿名网友 2019-04-08 20:00:18

老外写的,很强大,潜心学习一下