|
@@ -1,27 +1,27 @@
|
|
|
#include "StdAfx.h"
|
|
|
-#include "IOCPModel.h"
|
|
|
-#include "MainDlg.h"
|
|
|
+#include "PipeService.h"
|
|
|
+//#include "MainDlg.h"
|
|
|
|
|
|
-// 姣忎竴涓��鐞嗗櫒涓婁骇鐢熷�灏戜釜绾跨▼(涓轰簡鏈€澶ч檺搴︾殑鎻愬崌鏈嶅姟鍣ㄦ€ц兘锛岃�瑙侀厤濂楁枃妗�)
|
|
|
+#define PIPENAME _T("\\\\.\\pipe\\Assist")
|
|
|
+// 每一个处理器上产生多少个线程(为了最大限度的提升服务器性能,详见配套文档)
|
|
|
#define WORKER_THREADS_PER_PROCESSOR 2
|
|
|
-// 鍚屾椂鎶曢€掔殑Accept璇锋眰鐨勬暟閲�(杩欎釜瑕佹牴鎹�疄闄呯殑鎯呭喌鐏垫椿璁剧疆)
|
|
|
+// 同时投递的Accept请求的数量(这个要根据实际的情况灵活设置)
|
|
|
#define MAX_POST_ACCEPT 10
|
|
|
-// 浼犻€掔粰Worker绾跨▼鐨勯€€鍑轰俊鍙�
|
|
|
+// 传递给Worker线程的退出信号
|
|
|
#define EXIT_CODE NULL
|
|
|
|
|
|
|
|
|
-// 閲婃斁鎸囬拡鍜屽彞鏌勮祫婧愮殑瀹�
|
|
|
+// 释放指针和句柄资源的宏
|
|
|
|
|
|
-// 閲婃斁鎸囬拡瀹�
|
|
|
+// 释放指针宏
|
|
|
#define RELEASE(x) {if(x != NULL ){delete x;x=NULL;}}
|
|
|
-// 閲婃斁鍙ユ焺瀹�
|
|
|
+// 释放句柄宏
|
|
|
#define RELEASE_HANDLE(x) {if(x != NULL && x!=INVALID_HANDLE_VALUE){ CloseHandle(x);x = NULL;}}
|
|
|
-// 閲婃斁Socket瀹�
|
|
|
+// 释放Socket宏
|
|
|
#define RELEASE_SOCKET(x) {if(x !=INVALID_SOCKET) { closesocket(x);x=INVALID_SOCKET;}}
|
|
|
|
|
|
|
|
|
-
|
|
|
-CIOCPModel::CIOCPModel(void)
|
|
|
+CIOCPPipe::CIOCPPipe(void)
|
|
|
{
|
|
|
m_nThreads = 0;
|
|
|
m_hShutdownEvent = NULL;
|
|
@@ -30,71 +30,71 @@ CIOCPModel::CIOCPModel(void)
|
|
|
m_pMain = NULL;
|
|
|
}
|
|
|
|
|
|
-CIOCPModel::~CIOCPModel(void)
|
|
|
+CIOCPPipe::~CIOCPPipe(void)
|
|
|
{
|
|
|
- // 纭�繚璧勬簮褰诲簳閲婃斁
|
|
|
+ // 确保资源彻底释放
|
|
|
this->Stop();
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-///////////////////////////////////////////////////////////////////
|
|
|
-// 宸ヤ綔鑰呯嚎绋嬶細 涓篒OCP璇锋眰鏈嶅姟鐨勫伐浣滆€呯嚎绋�
|
|
|
-// 涔熷氨鏄�瘡褰撳畬鎴愮�鍙d笂鍑虹幇浜嗗畬鎴愭暟鎹�寘锛屽氨灏嗕箣鍙栧嚭鏉ヨ繘琛屽�鐞嗙殑绾跨▼
|
|
|
-///////////////////////////////////////////////////////////////////
|
|
|
-
|
|
|
-DWORD WINAPI CIOCPModel::_WorkerThread(LPVOID lpParam)
|
|
|
+DWORD WINAPI CIOCPPipe::_WorkerThread(LPVOID lpParam)
|
|
|
{
|
|
|
THREADPARAMS_WORKER* pParam = (THREADPARAMS_WORKER*)lpParam;
|
|
|
- CIOCPModel* pIOCPModel = (CIOCPModel*)pParam->pIOCPModel;
|
|
|
+ CIOCPPipe* pIOCPModel = (CIOCPPipe*)pParam->pIOCPModel;
|
|
|
int nThreadNo = (int)pParam->nThreadNo;
|
|
|
|
|
|
- pIOCPModel->_ShowMessage("宸ヤ綔鑰呯嚎绋嬪惎鍔�紝ID: %d.",nThreadNo);
|
|
|
+ pIOCPModel->_ShowMessage(_T("工作者线程启动,ID: %d."),nThreadNo);
|
|
|
|
|
|
OVERLAPPED *pOverlapped = NULL;
|
|
|
- PER_SOCKET_CONTEXT *pSocketContext = NULL;
|
|
|
+ ULONG_PTR pCompletionKey = NULL;
|
|
|
DWORD dwBytesTransfered = 0;
|
|
|
|
|
|
- // 寰�幆澶勭悊璇锋眰锛岀煡閬撴帴鏀跺埌Shutdown淇℃伅涓烘�
|
|
|
+ // 循环处理请求,知道接收到Shutdown信息为止
|
|
|
while (WAIT_OBJECT_0 != WaitForSingleObject(pIOCPModel->m_hShutdownEvent, 0))
|
|
|
{
|
|
|
BOOL bReturn = GetQueuedCompletionStatus(
|
|
|
pIOCPModel->m_hIOCompletionPort,
|
|
|
&dwBytesTransfered,
|
|
|
- (PULONG_PTR)&pSocketContext,
|
|
|
+ &pCompletionKey,
|
|
|
&pOverlapped,
|
|
|
INFINITE);
|
|
|
|
|
|
- // 濡傛灉鏀跺埌鐨勬槸閫€鍑烘爣蹇楋紝鍒欑洿鎺ラ€€鍑�
|
|
|
- if ( EXIT_CODE==(DWORD)pSocketContext )
|
|
|
+ dprintf(_T("IOCP有消息"));
|
|
|
+
|
|
|
+ // 如果收到的是退出标志,则直接退出
|
|
|
+ if ( EXIT_CODE==(DWORD)pCompletionKey )
|
|
|
{
|
|
|
- break;
|
|
|
+ //break;
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
- // 鍒ゆ柇鏄�惁鍑虹幇浜嗛敊璇�
|
|
|
+ // 判断是否出现了错误
|
|
|
if( !bReturn )
|
|
|
{
|
|
|
DWORD dwErr = GetLastError();
|
|
|
|
|
|
- // 鏄剧ず涓€涓嬫彁绀轰俊鎭�
|
|
|
- if( !pIOCPModel->HandleError( pSocketContext,dwErr ) )
|
|
|
+ // 显示一下提示信息
|
|
|
+ // 读取传入的参数
|
|
|
+ PER_IO_CONTEXT* pIoContext = CONTAINING_RECORD(pOverlapped, PER_IO_CONTEXT, m_Overlapped);
|
|
|
+ if( !pIOCPModel->HandleError( pIoContext,dwErr ) )
|
|
|
{
|
|
|
- break;
|
|
|
+ //break;
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
continue;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // 璇诲彇浼犲叆鐨勫弬鏁�
|
|
|
+ // 读取传入的参数
|
|
|
PER_IO_CONTEXT* pIoContext = CONTAINING_RECORD(pOverlapped, PER_IO_CONTEXT, m_Overlapped);
|
|
|
|
|
|
- // 鍒ゆ柇鏄�惁鏈夊�鎴风�鏂�紑浜�
|
|
|
+ // 判断是否有客户端断开了
|
|
|
if((0 == dwBytesTransfered) && ( OP_RECV==pIoContext->m_OpType || OP_SEND==pIoContext->m_OpType))
|
|
|
{
|
|
|
- pIOCPModel->_ShowMessage( _T("瀹㈡埛绔� %s:%d 鏂�紑杩炴帴."),inet_ntoa(pSocketContext->m_ClientAddr.sin_addr), ntohs(pSocketContext->m_ClientAddr.sin_port) );
|
|
|
+ pIOCPModel->_ShowMessage( _T("客户端 %s:%d 断开连接."),pIoContext->chClientName, pIoContext->dwProcessId );
|
|
|
|
|
|
- // 閲婃斁鎺夊�搴旂殑璧勬簮
|
|
|
- pIOCPModel->_RemoveContext( pSocketContext );
|
|
|
+ // 释放掉对应的资源
|
|
|
+ pIOCPModel->_RemoveContext( pIoContext );
|
|
|
|
|
|
continue;
|
|
|
}
|
|
@@ -102,143 +102,106 @@ DWORD WINAPI CIOCPModel::_WorkerThread(LPVOID lpParam)
|
|
|
{
|
|
|
switch( pIoContext->m_OpType )
|
|
|
{
|
|
|
- // Accept
|
|
|
case OP_ACCEPT:
|
|
|
{
|
|
|
- // 涓轰簡澧炲姞浠g爜鍙��鎬э紝杩欓噷鐢ㄤ笓闂ㄧ殑_DoAccept鍑芥暟杩涜�澶勭悊杩炲叆璇锋眰
|
|
|
- pIOCPModel->_DoAccpet( pSocketContext, pIoContext );
|
|
|
+ pIOCPModel->_DoAccpet( pIoContext );
|
|
|
+ dprintf(_T("客户端连接成功"));
|
|
|
}
|
|
|
break;
|
|
|
-
|
|
|
- // RECV
|
|
|
case OP_RECV:
|
|
|
{
|
|
|
- // 涓轰簡澧炲姞浠g爜鍙��鎬э紝杩欓噷鐢ㄤ笓闂ㄧ殑_DoRecv鍑芥暟杩涜�澶勭悊鎺ユ敹璇锋眰
|
|
|
- pIOCPModel->_DoRecv( pSocketContext,pIoContext );
|
|
|
+ //pIOCPModel->_DoRecv( pSocketContext,pIoContext );
|
|
|
}
|
|
|
break;
|
|
|
-
|
|
|
- // SEND
|
|
|
- // 杩欓噷鐣ヨ繃涓嶅啓浜嗭紝瑕佷笉浠g爜澶��浜嗭紝涓嶅�鏄撶悊瑙o紝Send鎿嶄綔鐩稿�鏉ヨ�绠€鍗曚竴浜�
|
|
|
case OP_SEND:
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
break;
|
|
|
default:
|
|
|
- // 涓嶅簲璇ユ墽琛屽埌杩欓噷
|
|
|
- TRACE(_T("_WorkThread涓�殑 pIoContext->m_OpType 鍙傛暟寮傚父.\n"));
|
|
|
+ // 不应该执行到这里
|
|
|
+ TRACE(_T("_WorkThread中的 pIoContext->m_OpType 参数异常.\n"));
|
|
|
break;
|
|
|
- } //switch
|
|
|
- }//if
|
|
|
- }//if
|
|
|
-
|
|
|
- }//while
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- TRACE(_T("宸ヤ綔鑰呯嚎绋� %d 鍙烽€€鍑�.\n"),nThreadNo);
|
|
|
+ TRACE(_T("工作者线程 %d 号退出.\n"),nThreadNo);
|
|
|
|
|
|
- // 閲婃斁绾跨▼鍙傛暟
|
|
|
+ // 释放线程参数
|
|
|
RELEASE(lpParam);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-//====================================================================================
|
|
|
-//
|
|
|
-// 绯荤粺鍒濆�鍖栧拰缁堟�
|
|
|
-//
|
|
|
-//====================================================================================
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-//////////////////////////////////////////////////////////////////
|
|
|
-// 鍚�姩鏈嶅姟鍣�
|
|
|
-bool CIOCPModel::Start()
|
|
|
+bool CIOCPPipe::Start()
|
|
|
{
|
|
|
- // 鍒濆�鍖栫嚎绋嬩簰鏂ラ噺
|
|
|
+ // 初始化线程互斥量
|
|
|
InitializeCriticalSection(&m_csContextList);
|
|
|
|
|
|
- // 寤虹珛绯荤粺閫€鍑虹殑浜嬩欢閫氱煡
|
|
|
+ // 建立系统退出的事件通知
|
|
|
m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
|
|
- // 鍒濆�鍖朓OCP
|
|
|
+ // 初始化IOCP
|
|
|
if (false == _InitializeIOCP())
|
|
|
{
|
|
|
- this->_ShowMessage(_T("鍒濆�鍖朓OCP澶辫触锛乗n"));
|
|
|
+ this->_ShowMessage(_T("初始化IOCP失败!\n"));
|
|
|
return false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- this->_ShowMessage("\nIOCP鍒濆�鍖栧畬姣昞n.");
|
|
|
+ this->_ShowMessage(_T("\nIOCP初始化完毕\n."));
|
|
|
}
|
|
|
|
|
|
- // 鍒濆�鍖朣ocket
|
|
|
- if( false==_InitializeListenSocket() )
|
|
|
- {
|
|
|
- this->_ShowMessage(_T("Listen Socket鍒濆�鍖栧け璐ワ紒\n"));
|
|
|
- this->_DeInitialize();
|
|
|
- return false;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- this->_ShowMessage("Listen Socket鍒濆�鍖栧畬姣�.");
|
|
|
- }
|
|
|
|
|
|
- this->_ShowMessage(_T("绯荤粺鍑嗗�灏辩华锛岀瓑鍊欒繛鎺�....\n"));
|
|
|
+ this->_ShowMessage(_T("系统准备就绪,等候连接....\n"));
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// 寮€濮嬪彂閫佺郴缁熼€€鍑烘秷鎭�紝閫€鍑哄畬鎴愮�鍙e拰绾跨▼璧勬簮
|
|
|
-void CIOCPModel::Stop()
|
|
|
+void CIOCPPipe::Stop()
|
|
|
{
|
|
|
- // 婵€娲诲叧闂�秷鎭�€氱煡
|
|
|
+ // 激活关闭消息通知
|
|
|
SetEvent(m_hShutdownEvent);
|
|
|
|
|
|
for (int i = 0; i < m_nThreads; i++)
|
|
|
{
|
|
|
- // 閫氱煡鎵€鏈夌殑瀹屾垚绔�彛鎿嶄綔閫€鍑�
|
|
|
+ // 通知所有的完成端口操作退出
|
|
|
PostQueuedCompletionStatus(m_hIOCompletionPort, 0, (DWORD)EXIT_CODE, NULL);
|
|
|
}
|
|
|
|
|
|
- // 绛夊緟鎵€鏈夌殑瀹㈡埛绔�祫婧愰€€鍑�
|
|
|
+ // 等待所有的客户端资源退出
|
|
|
WaitForMultipleObjects(m_nThreads, m_phWorkerThreads, TRUE, INFINITE);
|
|
|
|
|
|
- // 娓呴櫎瀹㈡埛绔�垪琛ㄤ俊鎭�
|
|
|
+ // 清除客户端列表信息
|
|
|
this->_ClearContextList();
|
|
|
|
|
|
- // 閲婃斁鍏朵粬璧勬簮
|
|
|
+ // 释放其他资源
|
|
|
this->_DeInitialize();
|
|
|
|
|
|
- this->_ShowMessage("鍋滄�鐩戝惉\n");
|
|
|
+ this->_ShowMessage(_T("停止监听\n"));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-////////////////////////////////
|
|
|
-// 鍒濆�鍖栧畬鎴愮�鍙�
|
|
|
-bool CIOCPModel::_InitializeIOCP()
|
|
|
+bool CIOCPPipe::_InitializeIOCP()
|
|
|
{
|
|
|
- // 寤虹珛绗�竴涓�畬鎴愮�鍙�
|
|
|
+ // 建立第一个完成端口
|
|
|
m_hIOCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0 );
|
|
|
|
|
|
if ( NULL == m_hIOCompletionPort)
|
|
|
{
|
|
|
- this->_ShowMessage(_T("寤虹珛瀹屾垚绔�彛澶辫触锛侀敊璇�唬鐮�: %d!\n"), WSAGetLastError());
|
|
|
+ this->_ShowMessage(_T("建立完成端口失败!错误代码: %d!\n"), WSAGetLastError());
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- // 鏍规嵁鏈�満涓�殑澶勭悊鍣ㄦ暟閲忥紝寤虹珛瀵瑰簲鐨勭嚎绋嬫暟
|
|
|
+ // 根据本机中的处理器数量,建立对应的线程数
|
|
|
+#ifdef _DEBUG
|
|
|
+ m_nThreads = 1;
|
|
|
+#else
|
|
|
m_nThreads = WORKER_THREADS_PER_PROCESSOR * _GetNoOfProcessors();
|
|
|
-
|
|
|
- // 涓哄伐浣滆€呯嚎绋嬪垵濮嬪寲鍙ユ焺
|
|
|
+#endif
|
|
|
+
|
|
|
+ // 为工作者线程初始化句柄
|
|
|
m_phWorkerThreads = new HANDLE[m_nThreads];
|
|
|
|
|
|
- // 鏍规嵁璁$畻鍑烘潵鐨勬暟閲忓缓绔嬪伐浣滆€呯嚎绋�
|
|
|
+ // 根据计算出来的数量建立工作者线程
|
|
|
DWORD nThreadID;
|
|
|
for (int i = 0; i < m_nThreads; i++)
|
|
|
{
|
|
@@ -248,110 +211,21 @@ bool CIOCPModel::_InitializeIOCP()
|
|
|
m_phWorkerThreads[i] = ::CreateThread(0, 0, _WorkerThread, (void *)pThreadParams, 0, &nThreadID);
|
|
|
}
|
|
|
|
|
|
- TRACE(" 寤虹珛 _WorkerThread %d 涓�.\n", m_nThreads );
|
|
|
-
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/////////////////////////////////////////////////////////////////
|
|
|
-// 鍒濆�鍖朣ocket
|
|
|
-bool CIOCPModel::_InitializeListenSocket()
|
|
|
-{
|
|
|
- // AcceptEx 鍜� GetAcceptExSockaddrs 鐨凣UID锛岀敤浜庡�鍑哄嚱鏁版寚閽�
|
|
|
- GUID GuidAcceptEx = WSAID_ACCEPTEX;
|
|
|
- GUID GuidGetAcceptExSockAddrs = WSAID_GETACCEPTEXSOCKADDRS;
|
|
|
-
|
|
|
- // 鏈嶅姟鍣ㄥ湴鍧€淇℃伅锛岀敤浜庣粦瀹歋ocket
|
|
|
- struct sockaddr_in ServerAddress;
|
|
|
-
|
|
|
- // 鐢熸垚鐢ㄤ簬鐩戝惉鐨凷ocket鐨勪俊鎭�
|
|
|
- m_pListenContext = new PER_SOCKET_CONTEXT;
|
|
|
-
|
|
|
- // 闇€瑕佷娇鐢ㄩ噸鍙營O锛屽繀椤诲緱浣跨敤WSASocket鏉ュ缓绔婼ocket锛屾墠鍙�互鏀�寔閲嶅彔IO鎿嶄綔
|
|
|
- m_pListenContext->m_Socket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
|
|
|
- if (INVALID_SOCKET == m_pListenContext->m_Socket)
|
|
|
- {
|
|
|
- this->_ShowMessage("鍒濆�鍖朣ocket澶辫触锛岄敊璇�唬鐮�: %d.\n", WSAGetLastError());
|
|
|
- return false;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- TRACE("WSASocket() 瀹屾垚.\n");
|
|
|
- }
|
|
|
-
|
|
|
- // 灏哃isten Socket缁戝畾鑷冲畬鎴愮�鍙d腑
|
|
|
- if( NULL== CreateIoCompletionPort( (HANDLE)m_pListenContext->m_Socket, m_hIOCompletionPort,(DWORD)m_pListenContext, 0))
|
|
|
- {
|
|
|
- this->_ShowMessage("缁戝畾 Listen Socket鑷冲畬鎴愮�鍙eけ璐ワ紒閿欒�浠g爜: %d/n", WSAGetLastError());
|
|
|
- RELEASE_SOCKET( m_pListenContext->m_Socket );
|
|
|
- return false;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- TRACE("Listen Socket缁戝畾瀹屾垚绔�彛 瀹屾垚.\n");
|
|
|
- }
|
|
|
-
|
|
|
- // 濉�厖鍦板潃淇℃伅
|
|
|
- ZeroMemory((char *)&ServerAddress, sizeof(ServerAddress));
|
|
|
- ServerAddress.sin_family = AF_INET;
|
|
|
- // 杩欓噷鍙�互缁戝畾浠讳綍鍙�敤鐨処P鍦板潃锛屾垨鑰呯粦瀹氫竴涓�寚瀹氱殑IP鍦板潃
|
|
|
- //ServerAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
- ServerAddress.sin_addr.s_addr = inet_addr(m_strIP.GetString());
|
|
|
- ServerAddress.sin_port = htons(m_nPort);
|
|
|
-
|
|
|
- // 缁戝畾鍦板潃鍜岀�鍙�
|
|
|
- if (SOCKET_ERROR == bind(m_pListenContext->m_Socket, (struct sockaddr *) &ServerAddress, sizeof(ServerAddress)))
|
|
|
- {
|
|
|
- this->_ShowMessage("bind()鍑芥暟鎵ц�閿欒�.\n");
|
|
|
- return false;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- TRACE("bind() 瀹屾垚.\n");
|
|
|
- }
|
|
|
-
|
|
|
- // 寮€濮嬭繘琛岀洃鍚�
|
|
|
- if (SOCKET_ERROR == listen(m_pListenContext->m_Socket,SOMAXCONN))
|
|
|
- {
|
|
|
- this->_ShowMessage("Listen()鍑芥暟鎵ц�鍑虹幇閿欒�.\n");
|
|
|
- return false;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- TRACE("Listen() 瀹屾垚.\n");
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // 涓篈cceptEx 鍑嗗�鍙傛暟锛岀劧鍚庢姇閫扐cceptEx I/O璇锋眰
|
|
|
- for( int i=0;i<MAX_POST_ACCEPT;i++ )
|
|
|
- {
|
|
|
- // 鏂板缓涓€涓狪O_CONTEXT
|
|
|
- PER_IO_CONTEXT* pAcceptIoContext = m_pListenContext->GetNewIoContext();
|
|
|
-
|
|
|
- if( false==this->_PostAccept( pAcceptIoContext ) )
|
|
|
- {
|
|
|
- m_pListenContext->RemoveContext(pAcceptIoContext);
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- this->_ShowMessage( _T("鎶曢€� %d 涓狝cceptEx璇锋眰瀹屾瘯"),MAX_POST_ACCEPT );
|
|
|
+ _PostAccept();
|
|
|
+ TRACE(" 建立 _WorkerThread %d 个.\n", m_nThreads );
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-////////////////////////////////////////////////////////////
|
|
|
-// 鏈€鍚庨噴鏀炬帀鎵€鏈夎祫婧�
|
|
|
-void CIOCPModel::_DeInitialize()
|
|
|
+void CIOCPPipe::_DeInitialize()
|
|
|
{
|
|
|
- // 鍒犻櫎瀹㈡埛绔�垪琛ㄧ殑浜掓枼閲�
|
|
|
+ // 删除客户端列表的互斥量
|
|
|
DeleteCriticalSection(&m_csContextList);
|
|
|
|
|
|
- // 鍏抽棴绯荤粺閫€鍑轰簨浠跺彞鏌�
|
|
|
+ // 关闭系统退出事件句柄
|
|
|
RELEASE_HANDLE(m_hShutdownEvent);
|
|
|
|
|
|
- // 閲婃斁宸ヤ綔鑰呯嚎绋嬪彞鏌勬寚閽�
|
|
|
+ // 释放工作者线程句柄指针
|
|
|
for( int i=0;i<m_nThreads;i++ )
|
|
|
{
|
|
|
RELEASE_HANDLE(m_phWorkerThreads[i]);
|
|
@@ -359,34 +233,16 @@ void CIOCPModel::_DeInitialize()
|
|
|
|
|
|
RELEASE(m_phWorkerThreads);
|
|
|
|
|
|
- // 鍏抽棴IOCP鍙ユ焺
|
|
|
+ // 关闭IOCP句柄
|
|
|
RELEASE_HANDLE(m_hIOCompletionPort);
|
|
|
|
|
|
- // 鍏抽棴鐩戝惉Socket
|
|
|
- RELEASE(m_pListenContext);
|
|
|
-
|
|
|
- this->_ShowMessage("閲婃斁璧勬簮瀹屾瘯.\n");
|
|
|
+ _ShowMessage(_T("释放资源完毕.\n"));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-//====================================================================================
|
|
|
-//
|
|
|
-// 鎶曢€掑畬鎴愮�鍙h�姹�
|
|
|
-//
|
|
|
-//====================================================================================
|
|
|
-
|
|
|
-
|
|
|
-//////////////////////////////////////////////////////////////////
|
|
|
-// 鎶曢€扐ccept璇锋眰
|
|
|
-bool CIOCPModel::_PostAccept( PER_IO_CONTEXT* pAcceptIoContext )
|
|
|
+bool CIOCPPipe::_PostAccept()
|
|
|
{
|
|
|
- // 鍑嗗�鍙傛暟
|
|
|
- DWORD dwBytes = 0;
|
|
|
- pAcceptIoContext->m_OpType = OP_ACCEPT;
|
|
|
- OVERLAPPED *p_ol = &pAcceptIoContext->m_Overlapped;
|
|
|
-
|
|
|
HANDLE hPipeAccept = CreateNamedPipe(
|
|
|
- _T(""), // pipe name
|
|
|
+ PIPENAME, // pipe name
|
|
|
PIPE_ACCESS_DUPLEX | // read/write access
|
|
|
FILE_FLAG_OVERLAPPED, // overlapped mode
|
|
|
PIPE_TYPE_MESSAGE | // message-type pipe
|
|
@@ -398,6 +254,9 @@ bool CIOCPModel::_PostAccept( PER_IO_CONTEXT* pAcceptIoContext )
|
|
|
NMPWAIT_WAIT_FOREVER, // client time-out
|
|
|
NULL); // default security attributes
|
|
|
|
|
|
+ if ( hPipeAccept == INVALID_HANDLE_VALUE )
|
|
|
+ return false;
|
|
|
+
|
|
|
HANDLE hIOCP = CreateIoCompletionPort(hPipeAccept, m_hIOCompletionPort, 10001, 0);
|
|
|
if ( hIOCP == NULL )
|
|
|
{
|
|
@@ -411,183 +270,93 @@ bool CIOCPModel::_PostAccept( PER_IO_CONTEXT* pAcceptIoContext )
|
|
|
pMyOverlapped->m_PipeAccept = hPipeAccept;
|
|
|
BOOL bRet = ConnectNamedPipe(hPipeAccept, (LPOVERLAPPED)pMyOverlapped);
|
|
|
|
|
|
- if( FALSE == bRet )
|
|
|
- {
|
|
|
+ if( bRet )
|
|
|
+ {// 重叠IO或完成端口,返回的是Fase;
|
|
|
CloseHandle(hPipeAccept);
|
|
|
CloseHandle(hIOCP);
|
|
|
delete pMyOverlapped;
|
|
|
pMyOverlapped = NULL;
|
|
|
- _ShowMessage("鍒涘缓鐢ㄤ簬Accept鐨凱ipe澶辫触锛侀敊璇�唬鐮�: %d", GetLastError());
|
|
|
+ _ShowMessage(_T("创建用于Accept的Pipe失败!错误代码: %d"), GetLastError());
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-////////////////////////////////////////////////////////////
|
|
|
-// 鍦ㄦ湁瀹㈡埛绔�繛鍏ョ殑鏃跺€欙紝杩涜�澶勭悊
|
|
|
-// 娴佺▼鏈夌偣澶嶆潅锛屼綘瑕佹槸鐪嬩笉鎳傜殑璇濓紝灏辩湅閰嶅�鐨勬枃妗e惂....
|
|
|
-// 濡傛灉鑳界悊瑙h繖閲岀殑璇濓紝瀹屾垚绔�彛鐨勬満鍒朵綘灏辨秷鍖栦簡涓€澶у崐浜�
|
|
|
-
|
|
|
-// 鎬讳箣浣犺�鐭ラ亾锛屼紶鍏ョ殑鏄疞istenSocket鐨凜ontext锛屾垜浠�渶瑕佸�鍒朵竴浠藉嚭鏉ョ粰鏂拌繛鍏ョ殑Socket鐢�
|
|
|
-// 鍘熸潵鐨凜ontext杩樻槸瑕佸湪涓婇潰缁х画鎶曢€掍笅涓€涓狝ccept璇锋眰
|
|
|
-//
|
|
|
-bool CIOCPModel::_DoAccpet( PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT* pIoContext )
|
|
|
+bool CIOCPPipe::_DoAccpet( PER_IO_CONTEXT* pIoContext )
|
|
|
{
|
|
|
- SOCKADDR_IN* ClientAddr = NULL;
|
|
|
- SOCKADDR_IN* LocalAddr = NULL;
|
|
|
- int remoteLen = sizeof(SOCKADDR_IN), localLen = sizeof(SOCKADDR_IN);
|
|
|
-
|
|
|
- ///////////////////////////////////////////////////////////////////////////
|
|
|
- // 1. 棣栧厛鍙栧緱杩炲叆瀹㈡埛绔�殑鍦板潃淇℃伅
|
|
|
- // 杩欎釜 m_lpfnGetAcceptExSockAddrs 涓嶅緱浜嗗晩~~~~~~
|
|
|
- // 涓嶄絾鍙�互鍙栧緱瀹㈡埛绔�拰鏈�湴绔�殑鍦板潃淇℃伅锛岃繕鑳介『渚垮彇鍑哄�鎴风�鍙戞潵鐨勭�涓€缁勬暟鎹�紝鑰佸己澶т簡...
|
|
|
- this->m_lpfnGetAcceptExSockAddrs(pIoContext->m_wsaBuf.buf, pIoContext->m_wsaBuf.len - ((sizeof(SOCKADDR_IN)+16)*2),
|
|
|
- sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, (LPSOCKADDR*)&LocalAddr, &localLen, (LPSOCKADDR*)&ClientAddr, &remoteLen);
|
|
|
-
|
|
|
- this->_ShowMessage( _T("瀹㈡埛绔� %s:%d 杩炲叆."), inet_ntoa(ClientAddr->sin_addr), ntohs(ClientAddr->sin_port) );
|
|
|
- this->_ShowMessage( _T("瀹㈡埛棰� %s:%d 淇℃伅锛�%s."),inet_ntoa(ClientAddr->sin_addr), ntohs(ClientAddr->sin_port),pIoContext->m_wsaBuf.buf );
|
|
|
-
|
|
|
-
|
|
|
- //////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
- // 2. 杩欓噷闇€瑕佹敞鎰忥紝杩欓噷浼犲叆鐨勮繖涓�槸ListenSocket涓婄殑Context锛岃繖涓狢ontext鎴戜滑杩橀渶瑕佺敤浜庣洃鍚�笅涓€涓�繛鎺�
|
|
|
- // 鎵€浠ユ垜杩樺緱瑕佸皢ListenSocket涓婄殑Context澶嶅埗鍑烘潵涓€浠戒负鏂拌繛鍏ョ殑Socket鏂板缓涓€涓猄ocketContext
|
|
|
-
|
|
|
- PER_SOCKET_CONTEXT* pNewSocketContext = new PER_SOCKET_CONTEXT;
|
|
|
- pNewSocketContext->m_Socket = pIoContext->m_sockAccept;
|
|
|
- memcpy(&(pNewSocketContext->m_ClientAddr), ClientAddr, sizeof(SOCKADDR_IN));
|
|
|
-
|
|
|
- // 鍙傛暟璁剧疆瀹屾瘯锛屽皢杩欎釜Socket鍜屽畬鎴愮�鍙g粦瀹�(杩欎篃鏄�竴涓�叧閿��楠�)
|
|
|
- if( false==this->_AssociateWithIOCP( pNewSocketContext ) )
|
|
|
- {
|
|
|
- RELEASE( pNewSocketContext );
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- ///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
- // 3. 缁х画锛屽缓绔嬪叾涓嬬殑IoContext锛岀敤浜庡湪杩欎釜Socket涓婃姇閫掔�涓€涓猂ecv鏁版嵁璇锋眰
|
|
|
- PER_IO_CONTEXT* pNewIoContext = pNewSocketContext->GetNewIoContext();
|
|
|
- pNewIoContext->m_OpType = RECV_POSTED;
|
|
|
- pNewIoContext->m_sockAccept = pNewSocketContext->m_Socket;
|
|
|
- // 濡傛灉Buffer闇€瑕佷繚鐣欙紝灏辫嚜宸辨嫹璐濅竴浠藉嚭鏉�
|
|
|
- //memcpy( pNewIoContext->m_szBuffer,pIoContext->m_szBuffer,MAX_BUFFER_LEN );
|
|
|
-
|
|
|
- // 缁戝畾瀹屾瘯涔嬪悗锛屽氨鍙�互寮€濮嬪湪杩欎釜Socket涓婃姇閫掑畬鎴愯�姹備簡
|
|
|
- if( false==this->_PostRecv( pNewIoContext) )
|
|
|
- {
|
|
|
- pNewSocketContext->RemoveContext( pNewIoContext );
|
|
|
- return false;
|
|
|
- }
|
|
|
+ // 客户端连接后,发出指令:获取客户端注入进程信息;
|
|
|
+ pIoContext->m_OpType = OP_SEND;
|
|
|
+ _stprintf_s(pIoContext->chReply, _T("%s"), _T("1001\n"));
|
|
|
+ pIoContext->cbToWrite = sizeof(pIoContext->chReply);
|
|
|
+
|
|
|
+ BOOL fWrite = WriteFile(
|
|
|
+ pIoContext->m_PipeAccept,
|
|
|
+ pIoContext->chReply,
|
|
|
+ pIoContext->cbToWrite,
|
|
|
+ &pIoContext->cbToWrite,
|
|
|
+ (LPOVERLAPPED)pIoContext);
|
|
|
+
|
|
|
+ if (!fWrite) {
|
|
|
+ dprintf("WriteFie: dwWritten=%d,GLE=%d\n", pIoContext->cbToWrite, GetLastError());
|
|
|
+ }
|
|
|
|
|
|
- /////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
- // 4. 濡傛灉鎶曢€掓垚鍔燂紝閭d箞灏辨妸杩欎釜鏈夋晥鐨勫�鎴风�淇℃伅锛屽姞鍏ュ埌ContextList涓�幓(闇€瑕佺粺涓€绠$悊锛屾柟渚块噴鏀捐祫婧�)
|
|
|
- this->_AddToContextList( pNewSocketContext );
|
|
|
+ dprintf(_T("向客户端发消息"));
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
- // 5. 浣跨敤瀹屾瘯涔嬪悗锛屾妸Listen Socket鐨勯偅涓狪oContext閲嶇疆锛岀劧鍚庡噯澶囨姇閫掓柊鐨凙cceptEx
|
|
|
+ // 5. 使用完毕之后,把Listen Socket的那个IoContext重置,然后准备投递新的AcceptEx
|
|
|
pIoContext->ResetBuffer();
|
|
|
- return this->_PostAccept( pIoContext );
|
|
|
+ return this->_PostAccept( );
|
|
|
}
|
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// 鎶曢€掓帴鏀舵暟鎹��姹�
|
|
|
-bool CIOCPModel::_PostRecv( PER_IO_CONTEXT* pIoContext )
|
|
|
+bool CIOCPPipe::_PostRecv( PER_IO_CONTEXT* pIoContext )
|
|
|
{
|
|
|
- // 鍒濆�鍖栧彉閲�
|
|
|
+ // 初始化变量
|
|
|
DWORD dwFlags = 0;
|
|
|
DWORD dwBytes = 0;
|
|
|
- WSABUF *p_wbuf = &pIoContext->m_wsaBuf;
|
|
|
OVERLAPPED *p_ol = &pIoContext->m_Overlapped;
|
|
|
|
|
|
pIoContext->ResetBuffer();
|
|
|
- pIoContext->m_OpType = RECV_POSTED;
|
|
|
+ pIoContext->m_OpType = OP_RECV;
|
|
|
|
|
|
- // 鍒濆�鍖栧畬鎴愬悗锛岋紝鎶曢€扺SARecv璇锋眰
|
|
|
- int nBytesRecv = WSARecv( pIoContext->m_sockAccept, p_wbuf, 1, &dwBytes, &dwFlags, p_ol, NULL );
|
|
|
-
|
|
|
- // 濡傛灉杩斿洖鍊奸敊璇�紝骞朵笖閿欒�鐨勪唬鐮佸苟闈炴槸Pending鐨勮瘽锛岄偅灏辫�鏄庤繖涓�噸鍙犺�姹傚け璐ヤ簡
|
|
|
- if ((SOCKET_ERROR == nBytesRecv) && (WSA_IO_PENDING != WSAGetLastError()))
|
|
|
- {
|
|
|
- this->_ShowMessage("鎶曢€掔�涓€涓猈SARecv澶辫触锛�");
|
|
|
- return false;
|
|
|
- }
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-/////////////////////////////////////////////////////////////////
|
|
|
-// 鍦ㄦ湁鎺ユ敹鐨勬暟鎹�埌杈剧殑鏃跺€欙紝杩涜�澶勭悊
|
|
|
-bool CIOCPModel::_DoRecv( PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT* pIoContext )
|
|
|
+bool CIOCPPipe::_DoRecv( PER_IO_CONTEXT* pIoContext )
|
|
|
{
|
|
|
- // 鍏堟妸涓婁竴娆$殑鏁版嵁鏄剧ず鍑虹幇锛岀劧鍚庡氨閲嶇疆鐘舵€侊紝鍙戝嚭涓嬩竴涓猂ecv璇锋眰
|
|
|
- SOCKADDR_IN* ClientAddr = &pSocketContext->m_ClientAddr;
|
|
|
- this->_ShowMessage( _T("鏀跺埌 %s:%d 淇℃伅锛�%s"),inet_ntoa(ClientAddr->sin_addr), ntohs(ClientAddr->sin_port),pIoContext->m_wsaBuf.buf );
|
|
|
+ // 先把上一次的数据显示出现,然后就重置状态,发出下一个Recv请求
|
|
|
+
|
|
|
|
|
|
- // 鐒跺悗寮€濮嬫姇閫掍笅涓€涓猈SARecv璇锋眰
|
|
|
+ // 然后开始投递下一个WSARecv请求
|
|
|
return _PostRecv( pIoContext );
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-/////////////////////////////////////////////////////
|
|
|
-// 灏嗗彞鏌�(Socket)缁戝畾鍒板畬鎴愮�鍙d腑
|
|
|
-bool CIOCPModel::_AssociateWithIOCP( PER_SOCKET_CONTEXT *pContext )
|
|
|
+bool CIOCPPipe::_AssociateWithIOCP( PER_IO_CONTEXT* pIoContext )
|
|
|
{
|
|
|
- // 灏嗙敤浜庡拰瀹㈡埛绔�€氫俊鐨凷OCKET缁戝畾鍒板畬鎴愮�鍙d腑
|
|
|
- HANDLE hTemp = CreateIoCompletionPort((HANDLE)pContext->m_Socket, m_hIOCompletionPort, (DWORD)pContext, 0);
|
|
|
-
|
|
|
- if (NULL == hTemp)
|
|
|
- {
|
|
|
- this->_ShowMessage(("鎵ц�CreateIoCompletionPort()鍑虹幇閿欒�.閿欒�浠g爜锛�%d"),GetLastError());
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
+ // 将用于和客户端通信的SOCKET绑定到完成端口中
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-//====================================================================================
|
|
|
-//
|
|
|
-// ContextList 鐩稿叧鎿嶄綔
|
|
|
-//
|
|
|
-//====================================================================================
|
|
|
-
|
|
|
-
|
|
|
-//////////////////////////////////////////////////////////////
|
|
|
-// 灏嗗�鎴风�鐨勭浉鍏充俊鎭�瓨鍌ㄥ埌鏁扮粍涓�
|
|
|
-void CIOCPModel::_AddToContextList( PER_SOCKET_CONTEXT *pHandleData )
|
|
|
+void CIOCPPipe::_AddToContextList( PER_IO_CONTEXT* pIoContext )
|
|
|
{
|
|
|
EnterCriticalSection(&m_csContextList);
|
|
|
|
|
|
- m_arrayClientContext.Add(pHandleData);
|
|
|
+ //m_arrayClientContext.Add(pHandleData);
|
|
|
|
|
|
LeaveCriticalSection(&m_csContextList);
|
|
|
}
|
|
|
|
|
|
-////////////////////////////////////////////////////////////////
|
|
|
-// 绉婚櫎鏌愪釜鐗瑰畾鐨凜ontext
|
|
|
-void CIOCPModel::_RemoveContext( PER_SOCKET_CONTEXT *pSocketContext )
|
|
|
+void CIOCPPipe::_RemoveContext( PER_IO_CONTEXT* pIoContext )
|
|
|
{
|
|
|
EnterCriticalSection(&m_csContextList);
|
|
|
|
|
|
- for( int i=0;i<m_arrayClientContext.GetCount();i++ )
|
|
|
- {
|
|
|
- if( pSocketContext==m_arrayClientContext.GetAt(i) )
|
|
|
- {
|
|
|
- RELEASE( pSocketContext );
|
|
|
- m_arrayClientContext.RemoveAt(i);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
LeaveCriticalSection(&m_csContextList);
|
|
|
}
|
|
|
|
|
|
-////////////////////////////////////////////////////////////////
|
|
|
-// 娓呯┖瀹㈡埛绔�俊鎭�
|
|
|
-void CIOCPModel::_ClearContextList()
|
|
|
+void CIOCPPipe::_ClearContextList()
|
|
|
{
|
|
|
EnterCriticalSection(&m_csContextList);
|
|
|
|
|
@@ -601,43 +370,7 @@ void CIOCPModel::_ClearContextList()
|
|
|
LeaveCriticalSection(&m_csContextList);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-//====================================================================================
|
|
|
-//
|
|
|
-// 鍏朵粬杈呭姪鍑芥暟瀹氫箟
|
|
|
-//
|
|
|
-//====================================================================================
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// 鑾峰緱鏈�満鐨処P鍦板潃
|
|
|
-CString CIOCPModel::GetLocalIP()
|
|
|
-{
|
|
|
- // 鑾峰緱鏈�満涓绘満鍚�
|
|
|
- char hostname[MAX_PATH] = {0};
|
|
|
- gethostname(hostname,MAX_PATH);
|
|
|
- struct hostent FAR* lpHostEnt = gethostbyname(hostname);
|
|
|
- if(lpHostEnt == NULL)
|
|
|
- {
|
|
|
- return DEFAULT_IP;
|
|
|
- }
|
|
|
-
|
|
|
- // 鍙栧緱IP鍦板潃鍒楄〃涓�殑绗�竴涓�负杩斿洖鐨処P(鍥犱负涓€鍙颁富鏈哄彲鑳戒細缁戝畾澶氫釜IP)
|
|
|
- LPSTR lpAddr = lpHostEnt->h_addr_list[0];
|
|
|
-
|
|
|
- // 灏咺P鍦板潃杞�寲鎴愬瓧绗︿覆褰㈠紡
|
|
|
- struct in_addr inAddr;
|
|
|
- memmove(&inAddr,lpAddr,4);
|
|
|
- m_strIP = CString( inet_ntoa(inAddr) );
|
|
|
-
|
|
|
- return m_strIP;
|
|
|
-}
|
|
|
-
|
|
|
-///////////////////////////////////////////////////////////////////
|
|
|
-// 鑾峰緱鏈�満涓��鐞嗗櫒鐨勬暟閲�
|
|
|
-int CIOCPModel::_GetNoOfProcessors()
|
|
|
+int CIOCPPipe::_GetNoOfProcessors()
|
|
|
{
|
|
|
SYSTEM_INFO si;
|
|
|
|
|
@@ -646,72 +379,49 @@ int CIOCPModel::_GetNoOfProcessors()
|
|
|
return si.dwNumberOfProcessors;
|
|
|
}
|
|
|
|
|
|
-/////////////////////////////////////////////////////////////////////
|
|
|
-// 鍦ㄤ富鐣岄潰涓�樉绀烘彁绀轰俊鎭�
|
|
|
-void CIOCPModel::_ShowMessage(const CString szFormat,...) const
|
|
|
+void CIOCPPipe::_ShowMessage(const CString szFormat,...) const
|
|
|
{
|
|
|
- // 鏍规嵁浼犲叆鐨勫弬鏁版牸寮忓寲瀛楃�涓�
|
|
|
+ // 根据传入的参数格式化字符串
|
|
|
CString strMessage;
|
|
|
va_list arglist;
|
|
|
|
|
|
- // 澶勭悊鍙橀暱鍙傛暟
|
|
|
+ // 处理变长参数
|
|
|
va_start(arglist, szFormat);
|
|
|
strMessage.FormatV(szFormat,arglist);
|
|
|
va_end(arglist);
|
|
|
|
|
|
- // 鍦ㄤ富鐣岄潰涓�樉绀�
|
|
|
- CMainDlg* pMain = (CMainDlg*)m_pMain;
|
|
|
- if( m_pMain!=NULL )
|
|
|
- {
|
|
|
- pMain->AddInformation(strMessage);
|
|
|
- TRACE( strMessage+_T("\n") );
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
-// 鍒ゆ柇瀹㈡埛绔疭ocket鏄�惁宸茬粡鏂�紑锛屽惁鍒欏湪涓€涓�棤鏁堢殑Socket涓婃姇閫扺SARecv鎿嶄綔浼氬嚭鐜板紓甯�
|
|
|
-// 浣跨敤鐨勬柟娉曟槸灏濊瘯鍚戣繖涓猻ocket鍙戦€佹暟鎹�紝鍒ゆ柇杩欎釜socket璋冪敤鐨勮繑鍥炲€�
|
|
|
-// 鍥犱负濡傛灉瀹㈡埛绔�綉缁滃紓甯告柇寮€(渚嬪�瀹㈡埛绔�穿婧冩垨鑰呮嫈鎺夌綉绾跨瓑)鐨勬椂鍊欙紝鏈嶅姟鍣ㄧ�鏄�棤娉曟敹鍒板�鎴风�鏂�紑鐨勯€氱煡鐨�
|
|
|
+// 判断客户端Socket是否已经断开,否则在一个无效的Socket上投递WSARecv操作会出现异常
|
|
|
+// 使用的方法是尝试向这个socket发送数据,判断这个socket调用的返回值
|
|
|
+// 因为如果客户端网络异常断开(例如客户端崩溃或者拔掉网线等)的时候,服务器端是无法收到客户端断开的通知的
|
|
|
|
|
|
-bool CIOCPModel::_IsSocketAlive(SOCKET s)
|
|
|
+bool CIOCPPipe::_IsSocketAlive(SOCKET s)
|
|
|
{
|
|
|
int nByteSent=send(s,"",0,0);
|
|
|
if (-1 == nByteSent) return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-///////////////////////////////////////////////////////////////////
|
|
|
-// 鏄剧ず骞跺�鐞嗗畬鎴愮�鍙d笂鐨勯敊璇�
|
|
|
-bool CIOCPModel::HandleError( PER_SOCKET_CONTEXT *pContext,const DWORD& dwErr )
|
|
|
+bool CIOCPPipe::HandleError( PER_IO_CONTEXT *pIoContext,const DWORD& dwErr )
|
|
|
{
|
|
|
- // 濡傛灉鏄�秴鏃朵簡锛屽氨鍐嶇户缁�瓑鍚�
|
|
|
+ // 如果是超时了,就再继续等吧
|
|
|
if(WAIT_TIMEOUT == dwErr)
|
|
|
{
|
|
|
- // 纭��瀹㈡埛绔�槸鍚﹁繕娲荤潃...
|
|
|
- if( !_IsSocketAlive( pContext->m_Socket) )
|
|
|
- {
|
|
|
- this->_ShowMessage( _T("妫€娴嬪埌瀹㈡埛绔�紓甯搁€€鍑猴紒") );
|
|
|
- this->_RemoveContext( pContext );
|
|
|
- return true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- this->_ShowMessage( _T("缃戠粶鎿嶄綔瓒呮椂锛侀噸璇曚腑...") );
|
|
|
- return true;
|
|
|
- }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- // 鍙�兘鏄��鎴风�寮傚父閫€鍑轰簡
|
|
|
+ // 可能是客户端异常退出了
|
|
|
else if( ERROR_NETNAME_DELETED==dwErr )
|
|
|
{
|
|
|
- this->_ShowMessage( _T("妫€娴嬪埌瀹㈡埛绔�紓甯搁€€鍑猴紒") );
|
|
|
- this->_RemoveContext( pContext );
|
|
|
+ this->_ShowMessage( _T("检测到客户端异常退出!") );
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
else
|
|
|
{
|
|
|
- this->_ShowMessage( _T("瀹屾垚绔�彛鎿嶄綔鍑虹幇閿欒�锛岀嚎绋嬮€€鍑恒€傞敊璇�唬鐮侊細%d"),dwErr );
|
|
|
+ this->_ShowMessage( _T("完成端口操作出现错误,线程退出。错误代码:%d"),dwErr );
|
|
|
return false;
|
|
|
}
|
|
|
}
|