//完成端口的部分代码 //主线程 //创建原始完成端口句柄 hIOCP=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0); if(NULL==hIOCP) { //错误处理 } //创建监听套节字 ListenPort()封装了bind listen等函数 SocketListen=ListenPort(); //绑定原始完成端口句柄到监听套节字SocketListen if(NULL==CreateIoCompletionPort((HANDLE)SocketListen,hIOCP,0,0)) { //错误处理 } //投递AcceptEx { unsigned long Num; unsigned long AcceptExNum; //GetConfigInt封装了读取配置文件 //得到可承受的突然并发连接数 AcceptExNum=GetConfigInt("Httpd","AcceptExNum",2000); //投递多个AccpetEx,PostAccpetEx封装了AccpetEx for(Num=0;Num<AcceptExNum;Num++) { PostAccpetEx(NULL); } } { //启动工作线程 unsigned long MaxWorkThread; unsigned long threadcount; DWORD dwThreadId; HANDLE* hThread; //读取配置文件中开启线程的数目 MaxWorkThread=GetConfigInt("Httpd","MaxWorkThread",2); //0代表根据CPU数目设置线程数目 CPU数目*2+2 if(MaxWorkThread<1) { SYSTEM_INFO systemInfo; GetSystemInfo(&systemInfo); MaxWorkThread=systemInfo.dwNumberOfProcessors*2+2; } hThread=HeapAlloc(GetProcessHeap(),0,sizeof(HANDLE)*MaxWorkThread); for(threadcount=0;threadcount<MaxWorkThread;threadcount++) { hThread[threadcount]=CreateThread(NULL,0,WorkerThread,hIOCP,0,&dwThreadId); } //等待工作线程退出,主线程进入阻塞状态 WaitForMultipleObjects(MaxWorkThread,hThread,TRUE,INFINITE); for(threadcount=0;threadcount<MaxWorkThread;threadcount++) { CloseHandle(hThread); } HeapFree(GetProcessHeap(),0,hThread); } //工作线程 //LOOP循环条件,根据情况设定相应的条件 while(LOOP) { BOOL Succes; P_IOCPDATA IOCPData;//自己定义的数据结构 unsigned long TransByte; LPWSAOVERLAPPED lpWsaOverlapped; //获取完成通知 //完成端口的精华就在这里 //通过调用GetQueuedCompletionStatus,线程可以获得原子性的时间段,避免了线程切换的开销 Succes= GetQueuedCompletionStatus( hIOCP, &TransByte, (unsigned long*)&IOCPData, &lpWsaOverlapped, INFINITE ); if(Succes&&NULL!=lpWsaOverlapped&&TransByte)//完全正常 { IOCPData=(P_IOCPDATA)lpWsaOverlapped; //根据不同的I/O类型进行不同的处理 switch(IOCPData->IOType) { //AcceptEx具有连接和接受的功能 case AcptDone: { //有一个AccpetEx完成,再投递一个AccpetEx PostAccpetEx(NULL); { //此段代码可以不调用,未发生错误,不知道为什么, //如果不调用的话,句柄不会很多,不会超出限制 /* //更行AccpetEx返回的套节字状态 int ErrorCode; ErrorCode= setsockopt( IOCPData->Socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&SocketListen, sizeof(SocketListen) ); if(SOCKET_ERROR==ErrorCode) { Test(); FreeIOCPData(IOCPData); continue; } */ } //绑定AccpetEx返回的套节字到hIOCP if(hIOCP!=CreateIoCompletionPort((HANDLE)IOCPData->Socket,hIOCP,(unsigned long)IOCPData,0)) { Test(); FreeIOCPData(IOCPData); continue; } //我写的是一个Web服务器,下面的是Http消息头的分析处理 if(HttpParseHead(IOCPData)) { Respons(IOCPData); } break; } //...... 其他处理情况 } } //.... 出现错误情况下的处理 } //做人要厚道 //转载请保留连接http://hi.baidu.com/xinglp //xlp1119@163.com,漫步黄昏