正文

基于完成端口的服务器端模型(转)2006-08-22 13:53:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lost/17759.html

分享到:

       Tag:完成端口    基于完成端口的服务器端模型   一:初始化套接字服务 WSAStartup() 二:创建完成端口 完成端口=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,工作线程数量); 三:创建指定数量的工作线程,运行它们,并在GetQueuedCompletionStatus调用中等待。 CreateThread(NULL,0,WorkThread,this,0,NULL); 四:创建监听套接字 监听套接字=WSASocket(AF_INET,SOCK_STREAM,0, NULL,0,WSA_FLAG_OVERLAPPED) 五:绑定,监听 bind(监听套接字, (PSOCKADDR) &addr, sizeof(addr); listen(监听套接字, 10) 六:创建监听线程 CreateThread(NULL,0,OnAccept,this,0,&dwThreadId);     创建完成端口其实是建立I/O投递的队列     监听线程中把完成端口与当前的客户端会话套接字绑定,这样此客户端会话的I/O信息就可以通过此完成端口进入投递队列,与此同时各个工作线程一直在调用GetQueuedCompletionStatus获取队列中的完成状态,一旦队列中有I/O投递,则当前工作线程就处理它,处理完成后,重新调用返回循环,继续调用GetQueuedCompletionStatus,处理各个客户端的下个投递请求。     监听线程把完成端口与当前的客户端会话套接字绑定后,则返回继续监听下个客户端的连接请求。     监听线程流程伪代码   while(1) {    SOCKET 客户端会话套接字;    //堵塞调用,直到有客户连接上来  客户端会话套接字=WSAAccept(监听套接字, NULL, NULL, NULL, 0); //把此客户端会话套接字绑定到完成端口,为重叠I/O数据结构分配内存 LPPER_HANDLE_DATA PerHandleData; CreateIoCompletionPort((HANDLE*)客户端会话套接字, 完成端口, (DWORD)PerHandleData, 0); //读取客户端首次数据 WSARecv(socket, &(PerHandleData->pIOContext->DataBuf), 1, &RecvBytes,  &Flags, &(PerHandleData->pIOContext->Overlapped), NULL) //以上处理好后,某个工作线程中调用GetQueuedCompletionStatus即可成功, 工作线程进入工作状态。        }   工作线程流程伪代码   while(1) {        //等待客户端I/O投递 bSuccess=GetQueuedCompletionStatus(完成端口, &dwNumBytes,                          //数据长度 (DWORD*)&PerHandleData,       //自定义结构 (OVERLAPPED**)&ConText,     //重叠结构 INFINITE);                                if(!bSuccess)        { //客户端断开连接 if(PerHandleData!=NULL) { if(dwNumBytes == 0 && PerHandleData->pIOContext->OperationType==RECV_POST)                      {                             pThis->CloseClient(PerHandleData);                      }               }        }        else        {               if(PerHandleData==NULL && dwNumBytes==0)               {                      //工作线程被通知结束                      SetEvent(g_ThreadHandles[pos]);                      return 0;               }                 //数据处理               dwRet=pThis->ProcessJob(PerHandleData->Socket, ConText,dwNumBytes);               if(dwRet==PROCESS_UNRECOGNIZED)               {                      pThis->CloseClient(PerHandleData);                      continue;               }               if(dwRet==PROCESS_FAIL)                      return 0;        } }  

阅读(3568) | 评论(1)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册