BOOL CHPThreadPool::DoAdjustThreadCount(DWORD dwNewThreadCount) { ASSERT((int)dwNewThreadCount >= 0); BOOL bRemove = FALSE; DWORD dwThreadCount = 0; { CCriSecLock lock(m_cs); if(dwNewThreadCount > m_dwThreadCount) { dwThreadCount = dwNewThreadCount - m_dwThreadCount; return CreateWorkerThreads(dwThreadCount); } else if(dwNewThreadCount < m_dwThreadCount) { bRemove = TRUE; dwThreadCount = m_dwThreadCount - dwNewThreadCount; m_dwThreadCount -= dwThreadCount; } } if(bRemove) { CMutexLock2 lock(m_mtx); for(DWORD i = 0; i < dwThreadCount; i++) m_cv.notify_one(); } return TRUE; }
BOOL CIocpServer::Start(LPCTSTR pszBindAddress, USHORT usPort) { if(!CheckParams() || !CheckStarting()) return FALSE; //创建监听套接字开始监听端口 if(CreateListenSocket(pszBindAddress, usPort)) { if(CreateCompletePort()) { if(CreateWorkerThreads()) { if(StartAcceptThread()) { m_enState = SS_STARTED; return TRUE; } } } } Stop(); return FALSE; }
BOOL CTcpAgent::Start(LPCTSTR pszBindAddress, BOOL bAsyncConnect) { if(!CheckParams() || !CheckStarting()) return FALSE; if(ParseBindAddress(pszBindAddress, bAsyncConnect)) if(CreateCompletePort()) if(CreateWorkerThreads()) { m_bAsyncConnect = bAsyncConnect; m_enState = SS_STARTED; return TRUE; } Stop(); return FALSE; }
BOOL CTcpServer::Start(LPCTSTR lpszBindAddress, USHORT usPort) { if(!CheckParams() || !CheckStarting()) return FALSE; PrepareStart(); if(CreateListenSocket(lpszBindAddress, usPort)) if(CreateCompletePort()) if(CreateWorkerThreads()) if(StartAccept()) { m_enState = SS_STARTED; return TRUE; } EXECUTE_RESTORE_ERROR(Stop()); return FALSE; }
BOOL CTcpServer::Start(LPCTSTR lpszBindAddress, USHORT usPort) { if(!CheckParams() || !CheckStarting()) return FALSE; PrepareStart(); if(CreateListenSocket(lpszBindAddress, usPort)) if(CreateCompletePort()) if(CreateWorkerThreads()) if(StartAccept()) { m_enState = SS_STARTED; return TRUE; } DWORD dwCode = ::GetLastError(); Stop(); ::SetLastError(dwCode); return FALSE; }
//启动网络服务器 //bMode启动模式,1:以客户端的方式启动,2:以服务器的方式启动 bool CServer::Start(BYTE bMode,CDataBlockAllocator* pDBAllocator, long nMaxFreeSockOperNum,long nMaxFreeIOOperNum,long lIOOperDataBufNum, bool bCheck,long lForbidTime, long lMaxMsgLen,long lMaxConNums,long lTotalClientsNum, long lPendingWrBufNum,long lPendingRdBufNum, long lMaxSendSizePerSecond,long lMaxRecvSizePerSecond, long lMaxBlockSendMsgNum, long lConPendingWrBufNum,long lConPendingRdBufNum, long lConMaxSendSizePerSecond,long lConMaxRecvSizePerSecond, long lConMaxBlockSendMsgNum) { m_bMode = bMode; m_pDBAllocator=pDBAllocator; m_nMaxFreeSockOperNum = nMaxFreeSockOperNum; m_nMaxFreeIOOperNum = nMaxFreeIOOperNum; m_lIOOperDataBufNum = lIOOperDataBufNum; m_bCheck = bCheck; m_lForbidTime = lForbidTime; m_lMaxMessageLength=lMaxMsgLen; m_lMaxClientConNum = lMaxConNums; m_lTotalClientsNum = lTotalClientsNum; m_lPendingWrBufNum = lPendingWrBufNum; m_lPendingRdBufNum=lPendingRdBufNum; m_lMaxSendSizePerSecond = lMaxSendSizePerSecond; m_lMaxRecvSizePerSecond = lMaxRecvSizePerSecond; m_lMaxBlockSendMsgNum = lMaxBlockSendMsgNum; m_lConPendingWrBufNum = lConPendingWrBufNum; m_lConPendingRdBufNum=lConPendingRdBufNum; m_lConMaxSendSizePerSecond= lConMaxSendSizePerSecond; m_lConMaxRecvSizePerSecond = lConMaxRecvSizePerSecond; m_lConMaxBlockSendMsgNum = lConMaxBlockSendMsgNum; //预分配命令操作结构 InitializeCriticalSection(&m_CSSockOper); InitializeCriticalSection(&m_CSMsgStat); uint i = 0; for(; i<m_nMaxFreeSockOperNum; i++) { tagSocketOper* pSockOper = new tagSocketOper(); m_FreeSocketOpers.push_back(pSockOper); } //预分配IO操作结构 InitializeCriticalSection(&m_CSIOOper); i = 0; for(; i<m_nMaxFreeIOOperNum; i++) { PER_IO_OPERATION_DATA* pPerIOData = new PER_IO_OPERATION_DATA(m_lIOOperDataBufNum); m_FreeListIOOpers.push_back(pPerIOData); } //初始化预分配的客户端 InitClients(); //得到CPU的数量 SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); //根据cpu数量创建完成端口 m_hCompletionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,sysInfo.dwNumberOfProcessors); //创建完成端口失败 if(m_hCompletionPort==NULL) { PutErrorString(NET_MODULE,"%-15s %s",__FUNCTION__,"创建完成端口失败!"); return false; } //创建网络主线程 bool bRet = CreateNetMainThread(); if(!bRet) { PutErrorString(NET_MODULE,"%-15s %s",__FUNCTION__,"创建网络主线程失败!"); return false; } //创建在完成端口上等待的工作者线程 bRet=CreateWorkerThreads(sysInfo.dwNumberOfProcessors); if(!bRet) { PutErrorString(NET_MODULE,"%-15s %s",__FUNCTION__,"创建工作线程失败!"); return false; } //客户端方式启动 if(bMode&0x1) { } //服务器方式启动 if(bMode&0x2) { //Host(dwPort,strIP,nSocketType); } //设置本机IP SetHostName(); return true; }
int main(int argc, char *argv[]) { SOCKET listener; SOCKET newsocket; WSADATA WsaData; struct sockaddr_in serverAddress; struct sockaddr_in clientAddress; int clientAddressLength; int err; CheckOsVersion(); err = WSAStartup (0x0101, &WsaData); if (err == SOCKET_ERROR) { FatalError("WSAStartup Failed"); return EXIT_FAILURE; } /* * Open a TCP socket connection to the server * By default, a socket is always opened * for overlapped I/O. Do NOT attach this * socket (listener) to the I/O completion * port! */ listener = socket(AF_INET, SOCK_STREAM, 0); if (listener < 0) { FatalError("socket() failed"); return EXIT_FAILURE; } /* * Bind our local address */ memset(&serverAddress, 0, sizeof(serverAddress)); serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(SERV_TCP_PORT); err = bind(listener, (struct sockaddr *)&serverAddress, sizeof(serverAddress) ); if (err < 0) FatalError("bind() failed"); ghCompletionPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, // No prior port 0, // No key 0 // Use default # of threads ); if (ghCompletionPort == NULL) FatalError("CreateIoCompletionPort() failed"); CreateWorkerThreads(ghCompletionPort); listen(listener, 5); fprintf(stderr, "Echo Server with I/O Completion Ports\n"); fprintf(stderr, "Running on TCP port %d\n", SERV_TCP_PORT); fprintf(stderr, "\nPress Ctrl+C to stop the server\n"); // // Loop forever accepting requests new connections // and starting reading from them. // for (;;) { struct ContextKey *pKey; clientAddressLength = sizeof(clientAddress); newsocket = accept(listener, (struct sockaddr *)&clientAddress, &clientAddressLength); if (newsocket < 0) { FatalError("accept() Failed"); return EXIT_FAILURE; } // Create a context key and initialize it. // calloc will zero the buffer pKey = calloc(1, sizeof(struct ContextKey)); pKey->sock = newsocket; pKey->ovOut.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // Set the event for writing so that packets // will not be sent to the completion port when // a write finishes. pKey->ovOut.hEvent = (HANDLE)((DWORD)pKey->ovOut.hEvent | 0x1); // Associate the socket with the completion port CreateIoCompletionPort( (HANDLE)newsocket, ghCompletionPort, (DWORD)pKey, // No key 0 // Use default # of threads ); // Kick off the first read IssueRead(pKey); } return 0; }