/* Wait for the specified network event to occur, or cancellation, whichever * happens first. On cancellation, return -1; on error, return the error * code; on success, return 0. */ int NetworkStream_Win32::WaitForCompletionOrCancellation( int iEvent ) { while(1) { int iRet = WaitForSingleObject( m_hCompletionEvent, INFINITE ); if( iRet != WAIT_OBJECT_0 ) continue; m_Mutex.Lock(); // This will reset the event. Do this while we hold the lock. WSANETWORKEVENTS events; WSAEnumNetworkEvents( m_Socket, m_hCompletionEvent, &events ); // Was the event signalled due to cancellation? if( m_State == STATE_CANCELLED ) { m_Mutex.Unlock(); return -1; } m_Mutex.Unlock(); // If the event didn't actually occur, keep waiting. if( (events.lNetworkEvents & (1<<iEvent)) ) return events.iErrorCode[iEvent]; /* If the socket was closed while we were waiting, stop. Note that when the * connection closes immediately after sending data, we'll receive both this * message and FD_READ at the same time. Only do this if the event we really * want hasn't happened yet. */ if( (events.lNetworkEvents & (1<<FD_CLOSE_BIT)) ) return WSAECONNRESET; } }
CAMLprim value win_check_connection (value socket, value kind, value idx) { CAMLparam3 (socket, kind, idx); WSANETWORKEVENTS evs; int res, err, i = Long_val(idx); D(printf("Check connection... %d\n", i)); if (WSAEnumNetworkEvents(Socket_val(socket), NULL, &evs)) { win32_maperr(WSAGetLastError ()); uerror("WSAEnumNetworkEvents", Nothing); } if (WSAEventSelect(Socket_val(socket), NULL, 0) == SOCKET_ERROR) { win32_maperr(WSAGetLastError ()); uerror("WSAEventSelect", Nothing); } if (!CloseHandle(events[i])) { win32_maperr(GetLastError ()); uerror("CloseHandle", Nothing); } err = evs.iErrorCode[(Long_val(kind) == 0) ? FD_CONNECT_BIT : FD_ACCEPT_BIT]; D(printf("Check connection: %ld, err %d\n", evs.lNetworkEvents, err)); if (err != 0) { win32_maperr(err); uerror("check_connection", Nothing); } CAMLreturn (Val_unit); }
unsigned WINAPI CW32SocketServer::thrdListenServer(LPVOID pParam) { CW32SocketServer* pThis = (CW32SocketServer*) pParam; DWORD dwWaitResult = 0; WSANETWORKEVENTS events; if ( !pThis ) return -1; // flag the thread to run pThis->m_bRun = true; while ( pThis->m_bRun ) { dwWaitResult = WSAWaitForMultipleEvents(1, &pThis->m_hListenEvent, TRUE, 1000, FALSE); if ( dwWaitResult == WSA_WAIT_EVENT_0 ) { WSAEnumNetworkEvents( pThis->m_sockListener, pThis->m_hListenEvent, &events ); if ( events.lNetworkEvents & FD_ACCEPT ) { pThis->AcceptConnection(); } if ( events.lNetworkEvents & FD_CLOSE ) { } } } return 0; }
static int ioctl_fd_maybe_socket (const struct fd_hook *remaining_list, gl_ioctl_fn primary, int fd, int request, void *arg) { SOCKET sock; WSANETWORKEVENTS ev; /* Test whether fd refers to a socket. */ sock = FD_TO_SOCKET (fd); ev.lNetworkEvents = 0xDEADBEEF; WSAEnumNetworkEvents (sock, NULL, &ev); if (ev.lNetworkEvents != 0xDEADBEEF) { /* fd refers to a socket. */ if (ioctlsocket (sock, request, arg) < 0) { set_winsock_errno (); return -1; } else return 0; } else /* Some other type of file descriptor. */ return execute_ioctl_hooks (remaining_list, primary, fd, request, arg); }
/* Reports current ready state * If one event in error_report_events has potential error code, the last WSA error code is set to that */ static int socket_update_events_unsafe(struct socket_file *f, int error_report_events) { WSANETWORKEVENTS events; WSAEnumNetworkEvents(f->socket, f->event_handle, &events); int e = 0; if (events.lNetworkEvents & FD_READ) e |= FD_READ; if (events.lNetworkEvents & FD_WRITE) e |= FD_WRITE; if (events.lNetworkEvents & FD_CONNECT) { e |= FD_CONNECT; f->shared->connect_error = events.iErrorCode[FD_CONNECT_BIT]; } if (events.lNetworkEvents & FD_ACCEPT) e |= FD_ACCEPT; if (events.lNetworkEvents & FD_CLOSE) e |= FD_CLOSE; int original = InterlockedOr(&f->shared->events, e); if (error_report_events & f->shared->events & FD_CONNECT) { WSASetLastError(f->shared->connect_error); f->shared->connect_error = 0; InterlockedAnd(&f->shared->events, ~FD_CONNECT); } return original | e; }
static unsigned int belle_sip_source_get_revents(belle_sip_source_t *s,belle_sip_pollfd_t *pfd){ WSANETWORKEVENTS revents={0}; int err; unsigned int ret=0; if (WaitForSingleObjectEx(s->fd,0,FALSE)==WAIT_OBJECT_0){ if (s->sock!=(belle_sip_socket_t)-1){ /*special treatments for windows sockets*/ err=WSAEnumNetworkEvents(s->sock,s->fd,&revents); if (err!=0){ belle_sip_error("WSAEnumNetworkEvents() failed: %s socket=%x",belle_sip_get_socket_error_string(),(unsigned int)s->sock); return 0; } if (revents.lNetworkEvents & FD_READ){ ret|=BELLE_SIP_EVENT_READ; } if (revents.lNetworkEvents & FD_WRITE){ ret|=BELLE_SIP_EVENT_WRITE; } s->armed_events=0; }else{ ret=BELLE_SIP_EVENT_READ; ResetEvent(s->fd); } } return ret; }
void Win32Socket::process_events() { WSANETWORKEVENTS events = { 0 }; int result = WSAEnumNetworkEvents(handle, event_handle, &events); throw_if_failed(result); bool receive_flag = false; bool send_flag = false; bool except_flag = false; if (events.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE)) receive_flag = true; if (events.lNetworkEvents & FD_WRITE) send_flag = true; if (events.lNetworkEvents & FD_OOB) except_flag = true; if (events.lNetworkEvents & FD_CONNECT) { if (events.iErrorCode[FD_CONNECT_BIT] == 0) send_flag = true; else except_flag = true; } if (receive_flag) SetEvent(receive_handle); if (send_flag) SetEvent(send_handle); if (except_flag) SetEvent(except_handle); }
static int _gl_close_fd_maybe_socket (int fd) { SOCKET sock = FD_TO_SOCKET (fd); WSANETWORKEVENTS ev; ev.lNetworkEvents = 0xDEADBEEF; WSAEnumNetworkEvents (sock, NULL, &ev); if (ev.lNetworkEvents != 0xDEADBEEF) { /* FIXME: other applications, like squid, use an undocumented _free_osfhnd free function. But this is not enough: The 'osfile' flags for fd also needs to be cleared, but it is hard to access it. Instead, here we just close twice the file descriptor. */ if (closesocket (sock)) { set_winsock_errno (); return -1; } else { /* This call frees the file descriptor and does a CloseHandle ((HANDLE) _get_osfhandle (fd)), which fails. */ _close (fd); return 0; } } else return _close (fd); }
WSANETWORKEVENTS WEventSocket::ReturnNetworkEvents() { WSANETWORKEVENTS events; // what the fired event data was memset(&events,0,sizeof(WSANETWORKEVENTS)); WSAEnumNetworkEvents(m_hSocket,m_hEvent,&events); // reset event to not set return events; }
DWORD WINAPI WorkerThread(LPVOID lpParam) { int ret, index; WSANETWORKEVENTS NetworkEvents; char szMessage[MSGSIZE]; while (TRUE) { ret = WSAWaitForMultipleEvents(g_iTotalConn, g_CliEventArr, FALSE, 1000, FALSE); if (ret == WSA_WAIT_FAILED || ret == WSA_WAIT_TIMEOUT) { continue; } index = ret - WSA_WAIT_EVENT_0; WSAEnumNetworkEvents(g_CliSocketArr[index], g_CliEventArr[index], &NetworkEvents); if (NetworkEvents.lNetworkEvents & FD_READ) { // Receive message from client ret = recv(g_CliSocketArr[index], szMessage, MSGSIZE, 0); if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)) { Cleanup(index); } else { szMessage[ret] = '\0'; send(g_CliSocketArr[index], szMessage, strlen(szMessage), 0); } } if (NetworkEvents.lNetworkEvents & FD_CLOSE) { Cleanup(index); } } return 0; }
//////////////////////////////////////////////////////////////////////////////// // 函数名:BOOL Connect( // SOCKET hSocket, // CONST struct sockaddr * pSocketAddr, // INT nAddrLen, // DWORD dwTimeout ) // 用 途:建立连接 // 对全局变量的影响:无 // 参 数: // hSocket : 用来建立连接到套接字 // pSocketAddr : SOCKADDR结构指针,代表目标地址 // nAddrLen : 地址结构的长度 // dwTimeout : 连接超时 // 返回值:BOOL //////////////////////////////////////////////////////////////////////////////// BOOL CBufSocket::Connect(SOCKET hSocket, CONST struct sockaddr * pSocketAddr, INT nAddrLen,DWORD dwTimeout) { HANDLE hConnectEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (hConnectEvent == NULL) { SetLastError( (INT)GetLastError() ); return FALSE; } // 注册FD_CONNECT事件 if( WSAEventSelect(hSocket, (WSAEVENT) hConnectEvent, FD_CONNECT) == SOCKET_ERROR) { CloseHandle(hConnectEvent); SetLastError( WSAGetLastError() ); return FALSE; } //与通讯方进行连接 INT nConnectResult = WSAConnect(hSocket, pSocketAddr, nAddrLen, NULL, NULL, NULL, NULL); INT nConnectError = WSAGetLastError(); if ((nConnectResult == SOCKET_ERROR) && (nConnectError == WSAEWOULDBLOCK)) { DWORD dwWaitResult = WSAWaitForMultipleEvents(1, &hConnectEvent, TRUE,dwTimeout, TRUE); if (dwWaitResult != WSA_WAIT_EVENT_0) { SetLastError( WSAGetLastError() ); nConnectResult = SOCKET_FAIL; } else { ////////////////////////////////////////////////////////////// /// 注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该 /// 进一步检查网络是否发生错误 /////////////////////////////////////////////////////////////// WSANETWORKEVENTS NetEvent; if(WSAEnumNetworkEvents(hSocket,(WSAEVENT)hConnectEvent,&NetEvent) == SOCKET_ERROR) { SetLastError( WSAGetLastError() ); nConnectResult = SOCKET_FAIL; } else if(NetEvent.iErrorCode[FD_CONNECT_BIT] !=0 ) // 发生错误 { SetLastError( NetEvent.iErrorCode[FD_CONNECT_BIT] ); nConnectResult = SOCKET_FAIL; } else nConnectResult = SOCKET_SUCCESS; //////////////////////////////////////////////////////////////// } } // 注销网络事件 WSAEventSelect(hSocket, (WSAEVENT) hConnectEvent, 0); CloseHandle(hConnectEvent); return (nConnectResult == SOCKET_SUCCESS)?TRUE:FALSE; }
//////////////////////////////////////////////////////////////////////////////// // 函数名:SOCKET Accept( // struct sockaddr * pSocketAddr, // LPINT nAddrLen, // DWORD dwTimeout /*= DEFAULT_ACCEPT_TIMEOUT*/ ) // 用 途:接受套接字连接 // 对全局变量的影响:无 // 参 数: // pSocketAddr : SOCKET地址 // nAddrLen : 地址参数的长度 // dwTimeout : 超时 // 返回值:SOCKET //////////////////////////////////////////////////////////////////////////////// SOCKET CBufSocket::Accept(struct sockaddr * pSocketAddr, LPINT nAddrLen,DWORD dwTimeout /*= DEFAULT_ACCEPT_TIMEOUT*/) { HANDLE hAcceptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (hAcceptEvent == NULL) { SetLastError( (INT)GetLastError() ); return (INVALID_SOCKET); } // 注册FD_ACCEPT事件 if( WSAEventSelect(m_hSocket, (WSAEVENT) hAcceptEvent, FD_ACCEPT) == SOCKET_ERROR) { CloseHandle(hAcceptEvent); SetLastError( WSAGetLastError() ); return (INVALID_SOCKET); } SOCKET hSocketAccept = WSAAccept(m_hSocket, pSocketAddr, nAddrLen, NULL, 0); INT nConnectError = WSAGetLastError(); if ((hSocketAccept == INVALID_SOCKET) && (nConnectError == WSAEWOULDBLOCK)) { // 阻塞 DWORD dwWaitResult = WSAWaitForMultipleEvents(1, &hAcceptEvent, TRUE,dwTimeout, TRUE); if (dwWaitResult == WSA_WAIT_EVENT_0) { ////////////////////////////////////////////////////////////// /// 注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该 /// 进一步检查网络是否发生错误 /////////////////////////////////////////////////////////////// WSANETWORKEVENTS NetEvent; if(WSAEnumNetworkEvents(m_hSocket,hAcceptEvent,&NetEvent) == SOCKET_ERROR) SetLastError( WSAGetLastError() ); else if(NetEvent.iErrorCode[FD_ACCEPT_BIT] !=0 ) // 发生错误 SetLastError( NetEvent.iErrorCode[FD_ACCEPT_BIT] ); else hSocketAccept = WSAAccept(m_hSocket, pSocketAddr, nAddrLen, NULL, 0); } else SetLastError( WSAGetLastError() ); } // 注销网络事件 WSAEventSelect( m_hSocket, (WSAEVENT) hAcceptEvent, 0); CloseHandle(hAcceptEvent); if (hSocketAccept != INVALID_SOCKET) { // 设置套接字的属性为地址可重用并且为非阻塞的 if ( !Block(hSocketAccept, 0) || !SetSocketOption(hSocketAccept) ) { closesocket(hSocketAccept); return (INVALID_SOCKET); } } return (hSocketAccept); }
static void _event_socket_prepare( EventHook hook ) { WSANETWORKEVENTS evts; /* look if some of the events we want already happened ? */ if (!WSAEnumNetworkEvents( hook->fh->fh_socket, NULL, &evts )) _event_socket_verify( hook, &evts ); }
CErrno NetReactorWES::iUpdate(INT32 start, INT32 end) { INT32 count = end - start; DWORD result = WaitForMultipleObjects(count, &m_pEvents[start], FALSE, 1); if (result >= WAIT_OBJECT_0 && result < (WAIT_OBJECT_0 + count)) { int index = result - WAIT_OBJECT_0 + start; INetHandlerPtr pNetHandler = m_pConnections[index]; WSANETWORKEVENTS events = { 0 }; WSAEnumNetworkEvents((SOCKET)pNetHandler->GetSession()->GetSocket(), m_pEvents[index], &events); bool bClosed = false; if (events.lNetworkEvents & FD_READ) { bClosed = !pNetHandler->OnMsgRecving().IsSuccess() || bClosed; } if (events.lNetworkEvents & FD_ACCEPT) { bClosed = !pNetHandler->OnMsgRecving().IsSuccess() || bClosed; } if (events.lNetworkEvents & FD_WRITE) { bClosed = !pNetHandler->OnMsgSending().IsSuccess() || bClosed; } if (events.lNetworkEvents & FD_CLOSE) { bClosed = true; } ISession * pSession = pNetHandler->GetSession(); if (pSession && pSession->GetObjTimeout().IsExpired() || pSession->IsClosed()) { bClosed = TRUE; } if (bClosed) { gDebugStream("delete curNodeName=" << pNetHandler->GetSession()->GetCurNodeName() << ":remoteName=" << pNetHandler->GetSession()->GetRemoteName() << ":address=" << pNetHandler->GetSession()->GetAddress() << ":port=" << pNetHandler->GetSession()->GetPort()); DelNetHandler(pNetHandler); pNetHandler->OnClose(); } } else if (result == WAIT_FAILED) { gDebugStream("***********Error***********" << "Wait Failed"); } else if (result >= WAIT_ABANDONED_0 && result < (WAIT_ABANDONED_0 + count)) { gDebugStream("***********Error***********" << "WAIT_ABANDONED_0" << result - WAIT_ABANDONED_0); } else if (result == WAIT_TIMEOUT) { } return CErrno::Success(); }
int main(int argc, char* argv[]) { WSADATA wsa; if(WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { printf("윈도우 소켓 초기화 실패! \n"); return -1; } // (socket + bind + listen) if(!CreateListenSocket()) { printf("대기 소켓 생성 실패\n"); return -1; } // 서버처리 //=================================================== int index = 0; WSANETWORKEVENTS neEvents; while(1) { // 이벤트 시그널 감지 index = WSAWaitForMultipleEvents(g_SockCnt, EventList, FALSE, WSA_INFINITE, FALSE); index -= WSA_WAIT_EVENT_0; // 이벤트 내용 가져오기 + EventList[index] 이벤트를 넌시그날로 변경 WSAEnumNetworkEvents( SockList[index], EventList[index], &neEvents); if(neEvents.lNetworkEvents & FD_ACCEPT) { EVENTERRORCHECK(neEvents, FD_ACCEPT_BIT); if(AddClient(index) != true) continue; } else if(neEvents.lNetworkEvents & FD_READ || neEvents.lNetworkEvents & FD_WRITE) { if(neEvents.iErrorCode[FD_READ_BIT] != 0 && neEvents.iErrorCode[FD_WRITE_BIT] != 0) { DisplayMessage(); return -1; } RecvClient(index); } else if(neEvents.lNetworkEvents & FD_CLOSE) { EVENTERRORCHECK(neEvents, FD_CLOSE_BIT); DeleteClient(index); } } //=================================================== WSACleanup(); return 0; }
// Function name : ReceiveBlockingTimeout // Description : // Return type : int // Argument : SOCKET sock // Argument : WSAEVENT event // Argument : char *buffer // Argument : int len // Argument : int flags // Argument : int timeout int ReceiveBlockingTimeout(SOCKET sock, WSAEVENT event, char *buffer, int len, int flags, int timeout) { int num_received, error; WSANETWORKEVENTS nevents; DWORD ret_val; num_received = recv(sock, buffer, len, flags); if (num_received == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEWOULDBLOCK) return error; } else { len -= num_received; buffer += num_received; } while (len) { ret_val = WSAWaitForMultipleEvents(1, &event, TRUE, timeout, FALSE); if (ret_val == WSA_WAIT_FAILED) return WSAGetLastError(); if (ret_val != WSA_WAIT_EVENT_0) return ret_val; if (WSAEnumNetworkEvents(sock, event, &nevents) == SOCKET_ERROR) return WSAGetLastError(); if (nevents.lNetworkEvents & FD_READ) { num_received = recv(sock, buffer, len, flags); if (num_received == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEWOULDBLOCK) return error; } else { len -= num_received; buffer += num_received; } } else { if (nevents.lNetworkEvents & FD_CLOSE) { return 1; } } } return 0; }
/* * Poll for the completion of non-blocking connect(). * If there's a completion, the function return the key of the completed * socket, and 'result' argument contains the connect() result. If connect() * succeeded, 'result' will have value zero, otherwise will have the error * code. */ static int check_connecting( pj_ioqueue_t *ioqueue ) { if (ioqueue->connecting_count) { int i, count; struct { pj_ioqueue_key_t *key; pj_status_t status; } events[PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL-1]; pj_lock_acquire(ioqueue->lock); for (count=0; count<PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL-1; ++count) { DWORD result; result = WaitForMultipleObjects(ioqueue->connecting_count, ioqueue->connecting_handles, FALSE, 0); if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0+ioqueue->connecting_count) { WSANETWORKEVENTS net_events; /* Got completed connect(). */ unsigned pos = result - WAIT_OBJECT_0; events[count].key = ioqueue->connecting_keys[pos]; /* See whether connect has succeeded. */ WSAEnumNetworkEvents((pj_sock_t)events[count].key->hnd, ioqueue->connecting_handles[pos], &net_events); events[count].status = PJ_STATUS_FROM_OS(net_events.iErrorCode[FD_CONNECT_BIT]); /* Erase socket from pending connect. */ erase_connecting_socket(ioqueue, pos); } else { /* No more events */ break; } } pj_lock_release(ioqueue->lock); /* Call callbacks. */ for (i=0; i<count; ++i) { if (events[i].key->cb.on_connect_complete) { events[i].key->cb.on_connect_complete(events[i].key, events[i].status); } } return count; } return 0; }
unsigned WINAPI CW32SocketServer::thrdClientServer(LPVOID pParam) { CSocketPool* pPool = (CSocketPool*) pParam; CW32SocketServer* pThis = pPool->GetOwner(); DWORD dwWaitResult = 0; int nIndex = 0; HANDLE arrHandles[WSA_MAXIMUM_WAIT_EVENTS]; stClientSocket* arrSockets[WSA_MAXIMUM_WAIT_EVENTS]; stClientSocket* pSocket = NULL; WSANETWORKEVENTS events; while ( pThis->m_bRun && pPool->GetSocketCount() ) { // create the handle array ZeroMemory(arrHandles, sizeof(arrHandles)); ZeroMemory(arrSockets, sizeof(arrSockets)); nIndex = 0; for ( int i = 0; i < WSA_MAXIMUM_WAIT_EVENTS; i++ ) { if ( (pSocket = pPool->GetSocket(i)) && !pSocket->bAvailable ) { arrSockets[nIndex] = pSocket; arrHandles[nIndex++] = pSocket->hEvent; } } // wait for an event to occur dwWaitResult = WSAWaitForMultipleEvents( (DWORD)nIndex, arrHandles, FALSE, 1000, FALSE ); if ( dwWaitResult != WSA_WAIT_FAILED && (dwWaitResult >= WSA_WAIT_EVENT_0) && (dwWaitResult <= (WSA_WAIT_EVENT_0 + nIndex -1)) ) { nIndex = dwWaitResult - WSA_WAIT_EVENT_0; if ( (pSocket = arrSockets[nIndex]) ) { WSAEnumNetworkEvents( pSocket->s, pSocket->hEvent, &events ); if ( events.lNetworkEvents & FD_READ ) { // data has arrived pThis->OnDataReceived(pSocket); } if ( events.lNetworkEvents & FD_WRITE ) { // data sent } if ( events.lNetworkEvents & FD_CLOSE ) { // socket closed pThis->OnClientSocketClosed(pSocket, (DWORD)events.iErrorCode[FD_CLOSE_BIT]); } } } } delete pPool; return 0; }
//////////////////////////////////////////////////////////////////////////////// // // FUNCTION: CIOCPServer::ListenThreadProc // // DESCRIPTION: Listens for incoming clients // // INPUTS: // // NOTES: // // MODIFICATIONS: // // Name Date Version Comments // N T ALMOND 06042001 1.0 Origin // //////////////////////////////////////////////////////////////////////////////// unsigned CIOCPServer::ListenThreadProc(LPVOID lParam) { CIOCPServer* pThis = reinterpret_cast<CIOCPServer*>(lParam); WSANETWORKEVENTS events; while(1) { // // Wait for something to happen // if (WaitForSingleObject(pThis->m_hKillEvent, 100) == WAIT_OBJECT_0) break; DWORD dwRet; dwRet = WSAWaitForMultipleEvents(1, &pThis->m_hEvent, FALSE, 100, FALSE); if (dwRet == WSA_WAIT_TIMEOUT) continue; // // Figure out what happened // int nRet = WSAEnumNetworkEvents(pThis->m_socListen, pThis->m_hEvent, &events); if (nRet == SOCKET_ERROR) { TRACE(_T("WSAEnumNetworkEvents error %ld\n"),WSAGetLastError()); break; } // Handle Network events // // ACCEPT if (events.lNetworkEvents & FD_ACCEPT) { if (events.iErrorCode[FD_ACCEPT_BIT] == 0) pThis->OnAccept(); else { TRACE(_T("Unknown network event error %ld\n"),WSAGetLastError()); break; } } } // while.... return 0; // Normal Thread Exit Code... }
UINT __stdcall CSvrSyncPlug::UdpThread(LPVOID lpVoid) { CSvrSyncPlug* pThis = reinterpret_cast<CSvrSyncPlug*>(lpVoid); SOCKET sck = socket(AF_INET, SOCK_DGRAM, 0); if (sck == INVALID_SOCKET) return 0; sockaddr_in addr = {0}; addr.sin_family = AF_INET; addr.sin_port = htons(5000); addr.sin_addr.s_addr = ADDR_ANY; if (SOCKET_ERROR == bind(sck, (PSOCKADDR)&addr, sizeof(addr))) { closesocket(sck); return 0; } int RecvBufSize = 0x10000; setsockopt(sck,SOL_SOCKET, SO_RCVBUF, (char*)&RecvBufSize, sizeof(int) ); setsockopt(sck,SOL_SOCKET, SO_SNDBUF, (char*)&RecvBufSize, sizeof(int) ); WSAEVENT hNetEvent = WSACreateEvent(); if (hNetEvent == NULL || SOCKET_ERROR == WSAEventSelect(sck, hNetEvent, FD_READ)) { closesocket(sck); return 0; } HANDLE hEvents[2] = {pThis->m_hExited, hNetEvent}; while (1) { DWORD ret = WSAWaitForMultipleEvents(_countof(hEvents), hEvents, FALSE,WSA_INFINITE, FALSE); if (ret == WAIT_OBJECT_0) break; else if (ret == WAIT_OBJECT_0 + 1) { WSANETWORKEVENTS NetworkEvents; WSAEnumNetworkEvents(sck, hNetEvent, &NetworkEvents); if(NetworkEvents.lNetworkEvents == FD_READ && NetworkEvents.iErrorCode[FD_READ_BIT] == 0) { char data[4096] = {0}; pkgheader* pheader = (pkgheader*)data; int len = recvfrom(sck, data, sizeof(data), 0, NULL, NULL); if (len > 0 && pheader->Length == len) { data[len] = 0; try { pThis->UdpProcess(data, len); } catch (...) {} } } } else break; } closesocket(sck); WSACloseEvent(hNetEvent); return 0; }
S32 tcp_open_channel(LLHost host) { // Open a TCP channel // Jump through some hoops to ensure that if the request hosts is down // or not reachable connect() does not block S32 handle; handle = socket(AF_INET, SOCK_STREAM, 0); if (!handle) { llwarns << "Error opening TCP control socket, socket() returned " << handle << llendl; return -1; } struct sockaddr_in address; address.sin_port = htons(host.getPort()); address.sin_family = AF_INET; address.sin_addr.s_addr = host.getAddress(); // Non blocking WSAEVENT hEvent=WSACreateEvent(); WSAEventSelect(handle, hEvent, FD_CONNECT) ; connect(handle, (struct sockaddr*)&address, sizeof(address)) ; // Wait fot 5 seconds, if we can't get a TCP channel open in this // time frame then there is something badly wrong. WaitForSingleObject(hEvent, 1000*5); // 5 seconds time out WSANETWORKEVENTS netevents; WSAEnumNetworkEvents(handle,hEvent,&netevents); // Check the async event status to see if we connected if ((netevents.lNetworkEvents & FD_CONNECT) == FD_CONNECT) { if (netevents.iErrorCode[FD_CONNECT_BIT] != 0) { llwarns << "Unable to open TCP channel, WSA returned an error code of " << netevents.iErrorCode[FD_CONNECT_BIT] << llendl; WSACloseEvent(hEvent); return -1; } // Now we are connected disable non blocking // we don't need support an async interface as // currently our only consumer (socks5) will make one round // of packets then just hold the connection open WSAEventSelect(handle, hEvent, NULL) ; unsigned long NonBlock = 0; ioctlsocket(handle, FIONBIO, &NonBlock); return handle; } llwarns << "Unable to open TCP channel, Timeout is the host up?" << netevents.iErrorCode[FD_CONNECT_BIT] << llendl; return -1; }
void RemoteDesktop::Network_Server::_Run(){ std::vector<WSAEVENT> EventArray; auto sharedrockarray = std::make_shared<std::vector<std::shared_ptr<SocketHandler>>>(); _Sockets = sharedrockarray; EventArray.reserve(WSA_MAXIMUM_WAIT_EVENTS); sharedrockarray->reserve(WSA_MAXIMUM_WAIT_EVENTS); SOCKET listensocket = RemoteDesktop::Listen(_Port, _Host); if (listensocket == INVALID_SOCKET) return; auto newevent = WSACreateEvent(); WSAEventSelect(listensocket, newevent, FD_ACCEPT | FD_CLOSE); EventArray.push_back(newevent); sharedrockarray->push_back(std::make_shared<SocketHandler>(listensocket, false)); NetworkProcessor processor(DELEGATE(&RemoteDesktop::Network_Server::_HandleReceive), DELEGATE(&RemoteDesktop::Network_Server::_HandleConnect)); WSANETWORKEVENTS NetworkEvents; auto timer = std::chrono::high_resolution_clock::now(); while (_Running && !EventArray.empty()) { auto Index = WSAWaitForMultipleEvents(EventArray.size(), EventArray.data(), FALSE, 1000, FALSE); if ((Index != WSA_WAIT_FAILED) && (Index != WSA_WAIT_TIMEOUT) && _Running) { WSAEnumNetworkEvents(sharedrockarray->at(Index)->get_Socket(), EventArray[Index], &NetworkEvents); if (((NetworkEvents.lNetworkEvents & FD_ACCEPT) == FD_ACCEPT) && NetworkEvents.iErrorCode[FD_ACCEPT_BIT] == ERROR_SUCCESS){ if (EventArray.size() >= WSA_MAXIMUM_WAIT_EVENTS - 1) continue;// ignore this event too many connections _HandleNewConnect(listensocket, EventArray, *sharedrockarray); } else if (((NetworkEvents.lNetworkEvents & FD_READ) == FD_READ) && NetworkEvents.iErrorCode[FD_READ_BIT] == ERROR_SUCCESS){ processor.Receive(sharedrockarray->at(Index)); } else if (((NetworkEvents.lNetworkEvents & FD_CLOSE) == FD_CLOSE) && NetworkEvents.iErrorCode[FD_CLOSE_BIT] == ERROR_SUCCESS){ if (Index == 0) {//stop all processing, set running to false and next loop will fail and cleanup _Running = false; continue; } } } //once every second send a keep alive. this will trigger disconnects if (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - timer).count() > 1000){ _CheckForDisconnects(EventArray, *sharedrockarray); timer = std::chrono::high_resolution_clock::now(); } } for (size_t beg = 1; beg < sharedrockarray->size(); beg++){ OnDisconnect(sharedrockarray->at(beg));//let all callers know about the disconnect, skip slot 0 which is the listen socket } //cleanup code here for (auto x : EventArray) WSACloseEvent(x); DEBUG_MSG("_Listen Exiting"); }
long reset_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd) { WSANETWORKEVENTS wne; if (WSAEnumNetworkEvents (sd, event->read, &wne) != 0) { msg (M_FATAL | M_ERRNO_SOCK, "Error: reset_net_event_win32: WSAEnumNetworkEvents call failed"); return 0; /* NOTREACHED */ } else return wne.lNetworkEvents; }
// Function name : ReceiveSome // Description : // Return type : int // Argument : SOCKET sock // Argument : WSAEVENT event // Argument : char *buffer // Argument : int len // Argument : int flags int ReceiveSome(SOCKET sock, WSAEVENT event, char *buffer, int len, int flags) { int num_received, error; WSANETWORKEVENTS nevents; DWORD ret_val; num_received = recv(sock, buffer, len, flags); if (num_received == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEWOULDBLOCK) return SOCKET_ERROR; } else { return num_received; } while (len) { ret_val = WSAWaitForMultipleEvents(1, &event, TRUE, INFINITE, FALSE); if (ret_val == WSA_WAIT_FAILED) return SOCKET_ERROR; if (ret_val != WSA_WAIT_EVENT_0) return SOCKET_ERROR; if (WSAEnumNetworkEvents(sock, event, &nevents) == SOCKET_ERROR) return SOCKET_ERROR; if (nevents.lNetworkEvents & FD_READ) { num_received = recv(sock, buffer, len, flags); if (num_received == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEWOULDBLOCK) return SOCKET_ERROR; } else return num_received; } else { if (nevents.lNetworkEvents & FD_CLOSE) { return SOCKET_ERROR; //return 0; } } } return 0; }
int AsyncEventPoller::Poll(int timeout) { if (fdEvents_.empty()) { UpdateTimer(); Sleep(timeout); return 0; } int count = 0; for (auto iter = eventFds_.begin(); iter != eventFds_.end(); ++iter) { events_[count++] = iter->first; } int nready = WSAWaitForMultipleEvents((DWORD)count, events_, FALSE, timeout, FALSE); if (nready == WSA_WAIT_FAILED) { LOG(ERROR) << "WSAWaitForMultipleEvents: " << LAST_ERROR_MSG; return 0; } else if (nready == WSA_WAIT_TIMEOUT) { UpdateTimer(); } else if (nready == WSA_WAIT_IO_COMPLETION) { // Alertable I/O } else { int index = nready - WSA_WAIT_EVENT_0; if (index >= WSA_MAXIMUM_WAIT_EVENTS) { LOG(ERROR) << "WSA wait events index out of range: " << index; return 0; } WSAEVENT hEvent = events_[index]; FdEntry* entry = eventFds_[hEvent]; WSANETWORKEVENTS events = {}; // This will reset the event object and adjust the status of // active FD events on the socket in an atomic fashion. int r = WSAEnumNetworkEvents(entry->fd, hEvent, &events); if (r == SOCKET_ERROR) { LOG(ERROR) << "WSAEnumNetworkEvents: " << LAST_ERROR_MSG; return 0; } HandleEvents(entry, &events); return 1; } return 0; }
int main(int argc, char* argv[]) { while (!initSock()); SOCKET sockServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sockServer == INVALID_SOCKET) { clearSock(sockServer); return -1; } sockaddr_in serverAddr = { 0 }; serverAddr.sin_family = AF_INET; serverAddr.sin_addr.S_un.S_addr = INADDR_ANY; serverAddr.sin_port = htons(PORT); if (bind(sockServer, (sockaddr*)&serverAddr, sizeof(sockaddr))) { clearSock(sockServer); return -1; } WSAEVENT listenEvent = WSACreateEvent(); long eventType = FD_ACCEPT | FD_CLOSE; WSAEventSelect(sockServer, listenEvent, eventType); printf("******************************************************************************\n"); printf("**********welcome to use the high-big-up server built by lancelot************"); printf("********************************************************************************\n"); printf("\nwaiting...\n"); if (listen(sockServer, SOMAXCONN) == SOCKET_ERROR) { clearSock(sockServer); printf("\n bye-bye \n"); return -1; } arrSocket[g_total] = sockServer; arrEvent[g_total++] = listenEvent; char buf[1024] = { 0 }; SOCKET sockClient = INVALID_SOCKET; WSANETWORKEVENTS netWorkEvent = { 0 }; long clientEventType = FD_CLOSE | FD_READ | FD_WRITE; while (true) { g_index = WSAWaitForMultipleEvents(g_total, arrEvent, false, 100, false); if (g_index == WSA_WAIT_TIMEOUT) continue; WSAEnumNetworkEvents(arrSocket[g_index - WSA_WAIT_EVENT_0], arrEvent[g_index - WSA_WAIT_EVENT_0], &netWorkEvent); if(!eventFunc(netWorkEvent, sockClient, buf, clientEventType)) continue; printf("get a message!\n"); } if (sockServer != INVALID_SOCKET) closesocket(sockServer); WSACleanup(); return 0; }
int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout) { struct epoll_event* ee; DWORD ct; FD_SET fdset[3]; WSANETWORKEVENTS wev; ee = &_epoll_events[epfd]; struct timeval tv, *tp; if (!ee) return -1; if (timeout < 0) tp = NULL; else { tv.tv_sec = timeout/1000; tv.tv_usec = (timeout%1000)*1000000; tp = &tv; } ct = GetTickCount(); while (GetTickCount() - ct < timeout) { int i, e = 0; for (i = 0; i < FD_SETSIZE; i++) { if (ee->fds[i] < 0) continue; if (WSAEnumNetworkEvents((SOCKET) ee->fds[i], NULL, &wev) == 0) { FD_ZERO(&fdset[0]); FD_ZERO(&fdset[1]); FD_ZERO(&fdset[2]); if (ee->events & EPOLLIN) FD_SET(ee->fds[i], &fdset[0]); if (ee->events & EPOLLOUT) FD_SET(ee->fds[i], &fdset[1]); if (ee->events & EPOLLERR) FD_SET(ee->fds[i], &fdset[2]); if (select(1, &fdset[0], &fdset[1], &fdset[2], tp) > 0 && (FD_ISSET(ee->fds[i], &fdset[0]) || FD_ISSET(ee->fds[i], &fdset[1]) || FD_ISSET(ee->fds[i], &fdset[2]))) { events[e++] = *ee; if (ee->events & EPOLLONESHOT) ee->fds[i] = -1; } } else { HANDLE h = (HANDLE) _get_osfhandle(ee->fds[i]); if (h != INVALID_HANDLE_VALUE && WaitForSingleObject(h, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0) { events[e++] = *ee; if (ee->events & EPOLLONESHOT) ee->fds[i] = -1; } } if (e >= maxevents) break; } if (e > 0) return e; if (timeout == -1) break; } return 0; }
UINT CMSocket::ThreadReadProc(LPVOID pParam) { CMSocket* pSocket = (CMSocket*) pParam; DWORD dwRecvd = SOCKET_BUFFER_SIZE; int ir, iCurrentBuffer = 0; CMSocket::SocketData* pData; ResetEvent(pSocket->m_hSocketThreadComplete); pSocket->m_iWriteOffset = 0; pSocket->m_hSocketEvent = WSACreateEvent(); if (SOCKET_ERROR != WSAEventSelect(pSocket->m_socket,pSocket->m_hSocketEvent,FD_READ | FD_CLOSE)) { WSANETWORKEVENTS wne; while (!pSocket->m_bDone) { dwRecvd = SOCKET_BUFFER_SIZE; WaitForSingleObject(pSocket->m_hSocketEvent,INFINITE); WSAEnumNetworkEvents(pSocket->m_socket,pSocket->m_hSocketEvent,&wne); switch(wne.lNetworkEvents) { case FD_READ: if (0 == wne.iErrorCode[FD_READ_BIT]) { pData = new CMSocket::SocketData(); ir = pSocket->Receive(pData->Buffer,SOCKET_BUFFER_SIZE); if (SOCKET_ERROR == ir) { int er = WSAGetLastError(); delete pData; ASSERT(0); } else { EnterCriticalSection(&pSocket->m_csIO); pData->iBufferSize = ir; pSocket->m_deqSocketData.push_back(pData); LeaveCriticalSection(&pSocket->m_csIO); } } break; case FD_CLOSE: pSocket->m_bDone = true; break; default: break; } } } SetEvent(pSocket->m_hSocketThreadComplete); return 0; }
void WSA_Async::Event_Proc(){ enum{NETWORK_EVENT=0,SYSTEM_EVENT,SIZE}; wstring res; WSANETWORKEVENTS events; DWORD dwResult; m_hWSAEvent=WSACreateEvent(); WSAEventSelect(m_socket->GetSocket(),m_hWSAEvent,FD_READ|FD_CLOSE); HANDLE hWSAEvents[SIZE]; hWSAEvents[NETWORK_EVENT]=m_hWSAEvent; hWSAEvents[SYSTEM_EVENT]=m_hEvent; while(running){ dwResult=WSAWaitForMultipleEvents(SIZE,hWSAEvents,FALSE,WSA_INFINITE,FALSE); if(dwResult==WSA_WAIT_FAILED){ break; } dwResult-=WSA_WAIT_EVENT_0; WSAResetEvent(hWSAEvents[dwResult]); if(dwResult==SYSTEM_EVENT){ while(pause&&running){ if(WSAWaitForMultipleEvents(1,&m_hEvent,FALSE,WSA_INFINITE,FALSE)==WSA_WAIT_FAILED){ break; } WSAResetEvent(m_hEvent); } }else{ wstring read; read.clear(); WSAEnumNetworkEvents(m_socket->GetSocket(),m_hWSAEvent,&events); switch(events.lNetworkEvents){ case FD_READ: m_socket->Recv(&read); m_call(events.lNetworkEvents,(wchar_t*)read.c_str()); break; case FD_CLOSE: m_socket->Reset(); m_call(events.lNetworkEvents,TEXT("")); running=false; break; } } } END: running=false; pause=false; WSAResetEvent(m_hEvent); WSACloseEvent(m_hWSAEvent); }
DWORD WINAPI ThreadProc( __in LPVOID lpParameter ) { int ret, index; DWORD cbTransferred; WSANETWORKEVENTS NetworkEvents; char szMessage[MSGSIZE]; while (TRUE) { ret = WSAWaitForMultipleEvents(g_iTotalConn, g_CliEventArr, FALSE, 1000, FALSE); if (ret == WSA_WAIT_FAILED || ret == WSA_WAIT_TIMEOUT) { continue; } index = ret - WSA_WAIT_EVENT_0; WSAEnumNetworkEvents(g_CliSocketArr[index], g_CliEventArr[index], &NetworkEvents); if (NetworkEvents.lNetworkEvents & FD_READ) { // Receive message from client ret = recv(g_CliSocketArr[index], szMessage, MSGSIZE, 0); if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)) { Cleanup(index); } else { // szMessage contains the received data szMessage[ret] = '/0'; //将接收到的消息返回 int sendCount,currentPosition=0,count=ret; while( count>0 && (sendCount=send(g_CliSocketArr[index] , szMessage+currentPosition,count,0))!=SOCKET_ERROR) { count-=sendCount; currentPosition+=sendCount; } if (NetworkEvents.lNetworkEvents & FD_CLOSE) { Cleanup(index); } } } } return 0; }