模型设计与实践---(八)完成端口(Complition port)

来源:互联网 发布:unity3d模型资源 编辑:程序博客网 时间:2024/05/10 04:29

socketCompletePort.h

/********************************************************************创建时间:2013/04/11文件名: socketCompletePort.h描述:完成端口I/O模型作者:fengshQQ  :19985430电子邮件:fengsh998@163.comBlog :      http://blog.csdn.net/fengsh998@CopyRight  fengsh*********************************************************************/#pragma once#include "socketbase.h"#include "socketArrays.h"typedef enum IOCP_WITH_TYPE {cpNone,cpRead,cpWrite};typedef struct tagIOCP{WSAOVERLAPPED overlap;WSABUF Buffer;char buf[BUFFERMAX];DWORD dwNumOfBytesRecved;DWORD Flags;IOCP_WITH_TYPE type;}PER_IOCP_DATA,*LPPER_IOCP_DATA;class CSocketCompletePort :public CSocketBase{private:bool initCompletionPort();int getSysProcessNum();public:CSocketCompletePort(void);~CSocketCompletePort(void);int startServer() ;int stopServer() ;bool sendtext(const std::string& content) ;void doIOCP(SOCKET client);void closeIOCP();LPPER_IOCP_DATA m_iocpdata;HANDLE m_completionport;private:void *wcid;void *tid;CSocketArrays *clients;};


socketCompletePort.cpp

#include "socketCompletePort.h"#include "socketThread.h"static void* wait_client_thread(void* param);static void* with_iocp_thread(void* param);CSocketCompletePort::CSocketCompletePort(void){m_completionport = INVALID_HANDLE_VALUE;m_iocpdata = NULL;clients = new CSocketArrays();}CSocketCompletePort::~CSocketCompletePort(void){delete clients;}bool CSocketCompletePort::initCompletionPort(){m_completionport = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);if (m_completionport==NULL){//创建完成端口失败!GetLastError());return false;}elsereturn true;//printf("创建完成端口成功!");}int CSocketCompletePort::getSysProcessNum(){SYSTEM_INFO sysInfo;GetSystemInfo(&sysInfo);return sysInfo.dwNumberOfProcessors;}int CSocketCompletePort::startServer(){if (initSocket() && initCompletionPort()){socket_thread_create(&wcid,wait_client_thread,(void*)this);int threadnum = getSysProcessNum();for (int i = 0; i < threadnum; i++){socket_thread_create(&tid,with_iocp_thread,(void*)this);}}return -1;}int CSocketCompletePort::stopServer(){dispatchcallback(cbServerClose,NULL);clients->clear();closesocket(m_listenSocket);return 1;}bool CSocketCompletePort::sendtext( const std::string& content ){for (int i = 0 ;i < clients->count();i++){//need to sure clients is valid.sendData(clients->getSocketByIndex(i),content);}return true;}void CSocketCompletePort::doIOCP( SOCKET client ){clients->addSocket(client);CreateIoCompletionPort((HANDLE)client,m_completionport,(DWORD)client,0);m_iocpdata = (LPPER_IOCP_DATA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PER_IOCP_DATA));m_iocpdata->Buffer.len=BUFFERMAX;m_iocpdata->Buffer.buf=m_iocpdata->buf;m_iocpdata->type = cpRead;WSARecv(client,&m_iocpdata->Buffer,1,&m_iocpdata->dwNumOfBytesRecved,&m_iocpdata->Flags,&m_iocpdata->overlap,NULL);}void CSocketCompletePort::closeIOCP(){PostQueuedCompletionStatus(m_completionport,0xFFFFFFFF,0,NULL);CloseHandle(m_completionport);}static void* wait_client_thread(void* param){CSocketCompletePort *iocp = (CSocketCompletePort*)param;DISPATCHPARAM dp;memset(&dp,0,sizeof(DISPATCHPARAM));SOCKET socketClient;while(true){SOCKADDR_IN addrClient;int addrClientSize=sizeof(SOCKADDR_IN);socketClient=accept(iocp->m_listenSocket,(struct sockaddr*)&addrClient,&addrClientSize);if (socketClient==INVALID_SOCKET){socketClient = NULL;if (iocp->checkSocketError(WSAGetLastError())){break;}continue;}else{iocp->doIOCP(socketClient);strcpy(dp.info.ip,inet_ntoa(addrClient.sin_addr));dp.info.port = addrClient.sin_port;iocp->dispatchcallback(cbHasConnect,&dp);}}iocp->closeIOCP();return 0;}static void* with_iocp_thread(void* param){CSocketCompletePort *iocp = (CSocketCompletePort*)param;DISPATCHPARAM dp;memset(&dp,0,sizeof(DISPATCHPARAM));HANDLE CompletionPort = iocp->m_completionport;DWORD dwByteTransferred;SOCKET socketClient;LPPER_IOCP_DATA lpPerIOData = NULL;while(true){GetQueuedCompletionStatus(CompletionPort,&dwByteTransferred,(PULONG_PTR)&socketClient,(LPWSAOVERLAPPED *)&lpPerIOData,INFINITE);if (dwByteTransferred == 0xFFFFFFFF){return 0;}if (lpPerIOData->type == cpRead){if (dwByteTransferred == 0){closesocket(socketClient);HeapFree(GetProcessHeap(),0,lpPerIOData);}else{strcpy(dp.msg,lpPerIOData->buf);//回调到界面iocp->dispatchcallback(cbCommunication,&dp);//回调到接收完成iocp->dispatchcallback(cbRecviced,NULL);memset(&lpPerIOData->overlap,0,sizeof(WSAOVERLAPPED));lpPerIOData->Buffer.len = BUFFERMAX;lpPerIOData->Buffer.buf = lpPerIOData->buf;lpPerIOData->type = cpRead;WSARecv(socketClient,&lpPerIOData->Buffer,1,&lpPerIOData->dwNumOfBytesRecved,&lpPerIOData->Flags,&lpPerIOData->overlap,NULL);}}}return 0;}