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; }
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; }