int MightyTCPEventSelectServer::acceptSocketObject()
{
	while(TRUE)
	{
		int nRet = ::WaitForSingleObject(m_ListenEvent,5*1000);
		if(nRet == WAIT_FAILED)
		{
			return -1;
		}
		else if(nRet == WSA_WAIT_TIMEOUT)	// 定时显式状态信息
		{
			
			continue;
		}
		else								// 有新的连接未决
		{
			::ResetEvent(m_ListenEvent);
			// 循环处理所有未决的连接请求
			while(TRUE)
			{
				sockaddr_in si;
				int nLen = sizeof(si);
				SOCKET sNew = ::accept(m_ListenSock, (sockaddr*)&si, &nLen);
				if(sNew == SOCKET_ERROR)
					break;
				PSOCKET_OBJ pSocket = GetSocketObj(sNew);
				pSocket->addrRemote = si;
				::WSAEventSelect(pSocket->s, pSocket->event, FD_READ|FD_CLOSE|FD_WRITE);
				AssignToFreeThread(pSocket);
			}
		}
	}
}
int main()
{
	USHORT nPort = 4567;	// 此服务器监听的端口号

	// 创建监听套节字
	SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);	
	sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(nPort);
	sin.sin_addr.S_un.S_addr = INADDR_ANY;
	if(::bind(sListen, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
	{
		printf(" Failed bind() \n");
		return -1;
	}
	::listen(sListen, 200);

	// 创建事件对象,并关联到监听的套节字
	WSAEVENT event = ::WSACreateEvent();
	::WSAEventSelect(sListen, event, FD_ACCEPT|FD_CLOSE);

	::InitializeCriticalSection(&g_cs);

	// 处理客户连接请求,打印状态信息
	while(TRUE)
	{
		int nRet = ::WaitForSingleObject(event, 5*1000);
		if(nRet == WAIT_FAILED)
		{
			printf(" Failed WaitForSingleObject() \n");
			break;
		}
		else if(nRet == WSA_WAIT_TIMEOUT)	// 定时显式状态信息
		{
			printf(" \n");
			printf("   TatolConnections: %d \n", g_nTatolConnections);
			printf(" CurrentConnections: %d \n", g_nCurrentConnections);
			continue;
		}
		else								// 有新的连接未决
		{
			::ResetEvent(event);
			// 循环处理所有未决的连接请求
			while(TRUE)
			{
				sockaddr_in si;
				int nLen = sizeof(si);
				SOCKET sNew = ::accept(sListen, (sockaddr*)&si, &nLen);
				if(sNew == SOCKET_ERROR)
					break;
				PSOCKET_OBJ pSocket = GetSocketObj(sNew);
				pSocket->addrRemote = si;
				::WSAEventSelect(pSocket->s, pSocket->event, FD_READ|FD_CLOSE|FD_WRITE);
				AssignToFreeThread(pSocket);
			}
		}
	}
	::DeleteCriticalSection(&g_cs);
	return 0;
}
Exemple #3
0
void LoopGMServer()
{

	HandleDataBuf(OnDispatchMessage);
	int nRet = WaitForSingleObject(ListenEvent, 100);
	if (nRet == WAIT_FAILED)
	{
		//printf("WaitForSingleObject Failed!\n");
		//break;
	}
	else if (nRet == WSA_WAIT_TIMEOUT)	//定时显示连接数
	{
		//printf("当前套接字连接数:%d\n", g_nCurrentConnections);
	}
	else	//有新的连接请求
	{
		ResetEvent(ListenEvent);
		while (true)
		{
			SOCKADDR_IN ClientAddr;
			int AddrLen = sizeof(ClientAddr);
			char sAct[64];
			SOCKET AcceptSock = accept(ServerSock, (LPSOCKADDR)&ClientAddr, &AddrLen);
			if (AcceptSock == SOCKET_ERROR)
			{
				break;
			}
			sprintf(sAct, "IP地址(%s)连接了区域服的GM服务\n", inet_ntoa(ClientAddr.sin_addr));
			AddInfo(sAct);
			LPSOCKET_OBJ pSockObj = CreateSocketObj(AcceptSock);
			pSockObj->m_clientaddr = ClientAddr;
			WSAEventSelect(pSockObj->m_socket, pSockObj->m_event, FD_READ | FD_WRITE | FD_CLOSE);
			AssignToFreeThread(pSockObj);
		}
	}
}
//
// Function: main
//
// Description:
//      This is the main program. It parses the command line and creates
//      the main socket. For UDP this socket is used to receive datagrams.
//      For TCP the socket is used to accept incoming client connections.
//      Each client TCP connection is handed off to a worker thread which
//      will receive any data on that connection until the connection is
//      closed.
//
int __cdecl main(int argc, char **argv)
{
    WSADATA          wsd;
    THREAD_OBJ      *thread=NULL;
    SOCKET_OBJ      *sockobj=NULL,
                    *newsock=NULL;
    int              index,
                     rc;
    struct addrinfo *res=NULL,
                    *ptr=NULL;

    // Validate the command line
    ValidateArgs(argc, argv);

    // Load Winsock
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        fprintf(stderr, "unable to load Winsock!\n");
        return -1;
    }

    printf("Local address: %s; Port: %s; Family: %d\n",
            gBindAddr, gBindPort, gAddressFamily);

    res = ResolveAddress(gBindAddr, gBindPort, gAddressFamily, gSocketType, gProtocol);
    if (res == NULL)
    {
        fprintf(stderr, "ResolveAddress failed to return any addresses!\n");
        return -1;
    }

    thread = GetThreadObj();

    // For each local address returned, create a listening/receiving socket
    ptr = res;
    while (ptr)
    {
        PrintAddress(ptr->ai_addr, ptr->ai_addrlen); printf("\n");

        sockobj = GetSocketObj(INVALID_SOCKET, (gProtocol == IPPROTO_TCP) ? TRUE : FALSE);

        // create the socket
        sockobj->s = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
        if (sockobj->s == INVALID_SOCKET)
        {
            fprintf(stderr,"socket failed: %d\n", WSAGetLastError());
            return -1;
        }

        InsertSocketObj(thread, sockobj);

        // bind the socket to a local address and port
        rc = bind(sockobj->s, ptr->ai_addr, ptr->ai_addrlen);
        if (rc == SOCKET_ERROR)
        {
            fprintf(stderr, "bind failed: %d\n", WSAGetLastError());
            return -1;
        }

        if (gProtocol == IPPROTO_TCP)
        {
            rc = listen(sockobj->s, 200);
            if (rc == SOCKET_ERROR)
            {
                fprintf(stderr, "listen failed: %d\n", WSAGetLastError());
                return -1;
            }

            // Register events on the socket
            rc = WSAEventSelect(
                    sockobj->s,
                    sockobj->event,
                    FD_ACCEPT | FD_CLOSE
                    );
            if (rc == SOCKET_ERROR)
            {
                fprintf(stderr, "WSAEventSelect failed: %d\n", WSAGetLastError());
                return -1;
            }
        }
        else
        {
            // Register events on the socket
            rc = WSAEventSelect(
                    sockobj->s,
                    sockobj->event,
                    FD_READ | FD_WRITE | FD_CLOSE
                    );
            if (rc == SOCKET_ERROR)
            {
                fprintf(stderr, "WSAEventSelect failed: %d\n", WSAGetLastError());
                return -1;
            }
        }

        ptr = ptr->ai_next;
    }
    // free the addrinfo structure for the 'bind' address
    freeaddrinfo(res);

    gStartTime = gStartTimeLast = GetTickCount();

    while (1)
    {
        rc = WaitForMultipleObjects(
                thread->SocketCount + 1,
                thread->Handles,
                FALSE,
                5000
                );
        if (rc == WAIT_FAILED)
        {
            fprintf(stderr, "WaitForMultipleObjects failed: %d\n", GetLastError());
            break;
        }
        else if (rc == WAIT_TIMEOUT)
        {
            PrintStatistics();
        }
        else
        {
            index = rc - WAIT_OBJECT_0;

            sockobj = FindSocketObj(thread, index-1);

            if (gProtocol == IPPROTO_TCP)
            {
                SOCKADDR_STORAGE sa;
                WSANETWORKEVENTS ne;
                SOCKET           sc;
                int              salen;

                rc = WSAEnumNetworkEvents(
                        sockobj->s,
                        thread->Handles[index],
                       &ne
                        );
                if (rc == SOCKET_ERROR)
                {
                    fprintf(stderr, "WSAEnumNetworkEvents failed: %d\n", WSAGetLastError());
                    break;
                }

                while (1)
                {
                    sc = INVALID_SOCKET;
                    salen = sizeof(sa);

                    //
                    // For TCP, accept the connection and hand off the client socket
                    // to a worker thread
                    //

                    sc = accept(
                            sockobj->s, 
                            (SOCKADDR *)&sa,
                            &salen
                               );
                    if ((sc == INVALID_SOCKET) && (WSAGetLastError() != WSAEWOULDBLOCK))
                    {
                        fprintf(stderr, "accept failed: %d\n", WSAGetLastError());
                        break;
                    }
                    else if (sc != INVALID_SOCKET)
                    {
                        newsock = GetSocketObj(INVALID_SOCKET, FALSE);

                        // Copy address information
                        memcpy(&newsock->addr, &sa, salen);
                        newsock->addrlen = salen;

                        newsock->s = sc;

                        InterlockedIncrement(&gTotalConnections);
                        InterlockedIncrement(&gCurrentConnections);

                        /*
                           printf("Accepted connection from: ");
                           PrintAddress((SOCKADDR *)&newsock->addr, newsock->addrlen);
                           printf("\n");
                         */

                        // Register for read, write and close on the client socket
                        rc = WSAEventSelect(
                                newsock->s,
                                newsock->event,
                                FD_READ | FD_WRITE | FD_CLOSE
                                           );
                        if (rc == SOCKET_ERROR)
                        {
                            fprintf(stderr, "WSAEventSelect failed: %d\n", WSAGetLastError());
                            break;
                        }

                        AssignToFreeThread(newsock);

                    }
                    else
                    {
                        // Failed with WSAEWOULDBLOCK -- just continue
                        break;
                    }
                }


            }
            else
            {
                // For UDP all we have to do is handle events on the main
                //    threads.
                if (HandleIo(thread, sockobj) == SOCKET_ERROR)
                {
                    RenumberThreadArray(thread);
                }
            }
        }
    }

    WSACleanup();
    return 0;
}