int HandleIOProcessTCPServer::threadrun(void * pBuf)
{
	while(TRUE)
	{
		//	等待网络事件
		int nIndex = ::WSAWaitForMultipleEvents(nSocketCount+1,events, FALSE, WSA_INFINITE, FALSE);
		nIndex = nIndex - WSA_WAIT_EVENT_0;
		// 查看受信的事件对象
		for(int i=nIndex; i<nSocketCount + 1; i++)
		{
			nIndex = ::WSAWaitForMultipleEvents(1, &events[i], TRUE, 1000, FALSE);
			if(nIndex == WSA_WAIT_FAILED || nIndex == WSA_WAIT_TIMEOUT)
			{
				continue;
			}
			else
			{
				if(i == 0)	// events[0]受信,重建数组
				{
					RebuildEventArray();
					// 如果没有客户I/O要处理了,则本线程退出
					if(nSocketCount == 0||m_exitCode==1)
					{
						DestroyAllSocket();
						_endthreadex(0);
						return 0;
					}
					::WSAResetEvent(events[0]);
				}
				else// 处理网络事件
				{
					// 查找对应的套节字对象指针,调用HandleIO处理网络事件
					//nIndex-WSA_WAIT_EVENT_0
					//WSA_MAXIMUM_WAIT_EVENTS
					PSOCKET_OBJ pSocket = (PSOCKET_OBJ)findSocket(events[i]);
					if(pSocket != NULL)
					{
						if(!HandleIO(pSocket))
							RebuildEventArray();
					}
					else
						printf(" Unable to find socket object \n ");
				}
			}
		}
	}
}
int MightyTCPCompletionPortServer::WorkProcess()
{
	PCompletionPort_BufObj pBuffer;
	DWORD dwKey;
	DWORD dwTrans;
	LPOVERLAPPED lpol;
	while(m_exitNotify==0)
	{
		// 在关联到此完成端口的所有套节字上等待I/O完成
		BOOL bOK = ::GetQueuedCompletionStatus(m_hCompletionPort,&dwTrans, (LPDWORD)&dwKey, (LPOVERLAPPED*)&lpol, WSA_INFINITE);

		if(dwTrans == -1) // 用户通知退出
		{
			::ExitThread(0);
		}
		pBuffer = CONTAINING_RECORD(lpol, CompletionPort_BufObj, wsaol);
		int nError = NO_ERROR;
		if(!bOK)						// 在此套节字上有错误发生
		{
			SOCKET s;
			if(pBuffer->nOperation == OP_ACCEPT)
			{
				s =m_ListenSock;
			}
			else
			{
				if(dwKey == 0)
					break;
				s = ((PCompletionPortIOObject)dwKey)->s;
			}
			DWORD dwFlags = 0;
			if(!::WSAGetOverlappedResult(s, &pBuffer->wsaol, &dwTrans, FALSE, &dwFlags))
			{
				nError = ::WSAGetLastError();
			}
		}
		HandleIO(dwKey, pBuffer, dwTrans, nError);
	}
	return 0;
}
Пример #3
0
void main()
{
    // 创建监听套节字,绑定到本地端口,进入监听模式
    int nPort = 4567;
    SOCKET sListen = ::WSASocket(
                         AF_INET, SOCK_STREAM, IPPROTO_TCP, //此三个参数与标准socket相同
                         NULL, //指定下层服务提供者,可以是NULL
                         0,    //保留
                         WSA_FLAG_OVERLAPPED); //指定socket属性,要使用重叠I/O模型,必须指定WSA_FLAG_OVERLAPPED
    //如果使用socket则默认指定WSA_FLAG_OVERLAPPED
    //绑定并监听IP和端口
    SOCKADDR_IN si;
    si.sin_family = AF_INET;
    si.sin_port = ::ntohs(nPort);
    si.sin_addr.S_un.S_addr = INADDR_ANY;
    ::bind(sListen, (sockaddr*)&si, sizeof(si));
    ::listen(sListen, 200);

    // 为监听套节字创建一个SOCKET_OBJ对象 GetSocketObj函数仅仅开辟一个PSOCKET_OBJ内存并将套接字传入,
    PSOCKET_OBJ pListen = GetSocketObj(sListen);

    // 加载扩展函数AcceptEx
    GUID GuidAcceptEx = WSAID_ACCEPTEX;
    DWORD dwBytes;
    //套接字选项和I/O控制命令  此处用来获取AcceptEx函数指针
    WSAIoctl(pListen->s,
             SIO_GET_EXTENSION_FUNCTION_POINTER,
             &GuidAcceptEx,
             sizeof(GuidAcceptEx),
             &pListen->lpfnAcceptEx,
             sizeof(pListen->lpfnAcceptEx),
             &dwBytes,
             NULL,
             NULL);

    g_pfnGetAcceptExSockaddrs = (LPFN_GETACCEPTEXSOCKADDRS)GetExtensionFuncPtr(pListen->s);
    // 创建用来重新建立g_events数组的事件对象
    g_events[0] = ::WSACreateEvent();

    // 在此可以投递多个接受I/O请求  投递5个接受连接请求
    for(int i=0; i<5; i++)
    {
        PostAccept(GetBufferObj(pListen, BUFFER_SIZE));
    }
    ::WSASetEvent(g_events[0]);

    while(TRUE)
    {
        int nIndex =
            ::WSAWaitForMultipleEvents(g_nBufferCount + 1, g_events, FALSE, WSA_INFINITE, FALSE);
        if(nIndex == WSA_WAIT_FAILED)
        {
            printf("WSAWaitForMultipleEvents() failed \n");
            break;
        }
        nIndex = nIndex - WSA_WAIT_EVENT_0;
        for(int i=0; i<=nIndex; i++)
        {
            int nRet = ::WSAWaitForMultipleEvents(1, &g_events[i], TRUE, 0, FALSE);
            if(nRet == WSA_WAIT_TIMEOUT)
                continue;
            else
            {
                ::WSAResetEvent(g_events[i]);
                // 重新建立g_events数组
                if(i == 0)
                {
                    RebuildArray();
                    continue;
                }

                // 处理这个I/O
                PBUFFER_OBJ pBuffer = FindBufferObj(g_events[i]);
                if(pBuffer != NULL)
                {
                    if(!HandleIO(pBuffer))
                        RebuildArray();
                }
            }
        }
    }
}