Esempio n. 1
0
static int AsynSelectLoop(void)
{
    size_t index;
    int nready;
    WSAEVENT hEvent;
    SOCKET sockfd;
    WSANETWORKEVENTS event_struct;

    if (g_count == 0)
    {
        Sleep(10);
        return 0;
    }
    nready = WSAWaitForMultipleEvents(g_count, g_events, FALSE, 100, FALSE);
    if (nready == WSA_WAIT_FAILED)
    {
        fprintf(stderr, ("WSAWaitForMultipleEvents() failed, %s"), LAST_ERROR_MSG);
        return -1;
    }
    else if (nready == WSA_WAIT_TIMEOUT)
    {
    }
    else if (nready == WSA_WAIT_IO_COMPLETION)
    {
    }
    else
    {
        index = WSA_WAIT_EVENT_0 + nready;
        if (index >= WSA_MAXIMUM_WAIT_EVENTS)
        {
            fprintf(stderr, "invalid event index: %d.\n", index);
            return -2;
        }
        sockfd = g_connections[index];
        hEvent = g_events[index];
        if (WSAEnumNetworkEvents(sockfd, hEvent, &event_struct) == SOCKET_ERROR)
        {
            fprintf(stderr, ("WSAEnumNetworkEvents() failed, %s"), LAST_ERROR_MSG);
            OnClose(sockfd, index, 0);
            return -3;
        }
        HandleEvents(sockfd, index, &event_struct);
    }
    return 0;
}
//
// This is the wait function used to keep track of events
//
int DoWait(WSAEVENT *Handles, Socklist *socklist)
{

    DWORD wait_rc = 0;
    WSAEVENT hTemp = WSA_INVALID_EVENT;
    Socklist socklTemp;

    int i = 0;

    //
    // Rotate the array, beginning at index 1, by one element.
    // This ensures that all handles get a fair chance to be serviced.
    //
    // There is no way to detect how many handles were signalled when
    // WSAWaitForMultipleObjects() returns. We simply pick the first one and 
    // come back to this function later
    // Without the rotation below, this has the potential for starving
    // connections accepted later.
    //
    // Index 0 is avoided, since it is our listening socket. 
    //
    for ( i = 1; i < curr_size-1; i++ )
    {
        hTemp = Handles[i+1];
        Handles[i+1] = Handles[i];
        Handles[i] = hTemp;

        socklTemp = socklist[i+1];
        socklist[i+1] = socklist[i];
        socklist[i] = socklTemp;
    }

    if(WSA_WAIT_FAILED == (wait_rc = WSAWaitForMultipleEvents(curr_size,
                                                              Handles,
                                                              FALSE,
                                                              WSA_INFINITE, 
                                                              FALSE
                                                              )))
    {
        ERR("WSAWaitForMultipleEvents()");
        return -1;
    }

    return(wait_rc - WSA_WAIT_EVENT_0);
}
Esempio n. 3
0
/*------------------------------------------------------------------------------------------------------------------
-- FUNCTION:	TimerThread
--
-- DATE:		Febuary 6th, 2016
--
-- REVISIONS:
--
-- DESIGNER:	Ruoqi Jia
--
-- PROGRAMMER:	Ruoqi Jia
--
-- INTERFACE:	DWORD WINAPI TimerThread(LPVOID lpParameter)
--
-- RETURNS: void
--
-- NOTES: Sets a timer for the UDP thread. If a packet didnt arrive in the given time it will timeout and close the
--			socket. It is used for when packets are dropped due to the nature of UDP and we need to determine if there
--			are anymore incoming traffics coming in to determine the end of transmission.
--------------------------------------------------------------------------------------------------------------------*/
DWORD WINAPI TimerThread(LPVOID lpParameter)
{
	LPSOCKET_INFORMATION SOCKET_INFO;
	WSAEVENT e[1];
	e[0] = TimerEvent;
	SOCKET_INFO = (LPSOCKET_INFORMATION)lpParameter;
	while (TRUE)
	{
		if (WSAWaitForMultipleEvents(1, e, FALSE, 100, FALSE) == WSA_WAIT_TIMEOUT)
		{
			EndOfTransmission = TRUE;
			WSACloseEvent(e[0]);
			return FALSE;
		}
		WSAResetEvent(e[0]);
	}
	return TRUE;
}
Esempio n. 4
0
DWORD
mono_win32_wsa_wait_for_multiple_events (DWORD count, const WSAEVENT FAR *handles, BOOL waitAll, DWORD timeout, BOOL alertable)
{
	DWORD result = WAIT_FAILED;
	MonoThreadInfo * const info = alertable ? mono_thread_info_current_unchecked () : NULL;

	if (info)
		enter_alertable_wait (info);

	result = WSAWaitForMultipleEvents (count, handles, waitAll, timeout, alertable);

	// NOTE, leave_alertable_wait should not affect GetLastError but
	// if changed, GetLastError needs to be preserved and reset before returning.
	if (info)
		leave_alertable_wait (info);

	return result;
}
Esempio n. 5
0
int tube_wait(struct tube* tube)
{
	/* block on eventhandle */
	DWORD res = WSAWaitForMultipleEvents(
		1 /* one event in array */, 
		&tube->event /* the event to wait for, our pipe signal */, 
		0 /* wait for all events is false */, 
		WSA_INFINITE /* wait, no timeout */,
		0 /* we are not alertable for IO completion routines */
		);
	if(res == WSA_WAIT_TIMEOUT) {
		return 0;
	}
	if(res == WSA_WAIT_IO_COMPLETION) {
		/* a bit unexpected, since we were not alertable */
		return 0;
	}
	return 1;
}
Esempio n. 6
0
  void EventTCPSocket::loop( HANDLE stopEvent, uint32_t idleTimeout, uint32_t closeTimeout )
  {
    if ( mSocket == INVALID_SOCKET )
      EXCEPT( L"Cannot loop, invalid socket" );

    WSAEVENT events[2] = { (WSAEVENT)stopEvent, mNetworkEvent };

    while ( mState != State_Closed )
    {
      DWORD wait = ( idleTimeout > 0 ? idleTimeout : WSA_INFINITE );
      if ( mState == State_Closing )
        wait = closeTimeout;

      DWORD event = WSAWaitForMultipleEvents( 2, events, FALSE, wait, FALSE );

      switch ( event )
      {
        case WSA_WAIT_FAILED:
          EXCEPT_WSA( L"Socket event wait failed" );
        break;
        case WSA_WAIT_TIMEOUT:
          if ( mState == State_Closing )
          {
            mCloseReason = Close_Unexpected;
            close();
          }
          else
          {
            for ( SocketListener* listener : mListeners )
              if ( listener->idleCallback( this ) )
                break;
          }
        break;
        case WSA_WAIT_EVENT_0:
          closeRequest();
        break;
        case WSA_WAIT_EVENT_0 + 1:
          process();
        break;
      }
    }
  }
Esempio n. 7
0
int
O2Agent::
connect2(SOCKET s, const struct sockaddr *name, int namelen, int timeout)
{
	bool err = false;

	WSAEVENT event = WSACreateEvent();
	if (event == WSA_INVALID_EVENT)
		err = true;

	if (!err && WSAEventSelect(s, event, FD_CONNECT) == SOCKET_ERROR)
		err = true;

	if (!err && connect(s, name, namelen) == SOCKET_ERROR) {
		if (WSAGetLastError() != WSAEWOULDBLOCK)
			err = true;
		//非ブロッキングでconnectした場合、通常はSOCKET_ERRORになり
		//WSAGetLastError() == WSAEWOULDBLOCKが返ってくる。
		//それ以外のエラーは本当にconnect失敗
	}
	else
		err = true;

	if (!err && WSAWaitForMultipleEvents(1, &event, FALSE, timeout, FALSE) != WSA_WAIT_EVENT_0)
		err = true;

	WSANETWORKEVENTS events;
	if (!err && WSAEnumNetworkEvents(s, event, &events) == SOCKET_ERROR)
		err = true;
	if (!err && (!(events.lNetworkEvents & FD_CONNECT) || events.iErrorCode[FD_CONNECT_BIT] != 0))
		err = true;

	WSAEventSelect(s, NULL, 0);
	WSACloseEvent(event);

	/* back to blocking mode
	ulong argp = 0;
	ioctlsocket(s, FIONBIO, &argp);
	*/

	return (err ? SOCKET_ERROR : 0);
}
Esempio n. 8
0
UDPPacket *UDPSocket::poll()
{
	if (WSAWaitForMultipleEvents(1, &event, false, 0, true) == WSA_WAIT_EVENT_0)
	{
		int len, FromLen = sizeof(INADDR);
		INADDR src;

		len = recvfrom(sid, packet.msg, PACKET_MAX_LENGTH, 0, src.getAddress(), &FromLen);

		if (len <= 0)
			return NULL;

		packet.src = src;
		packet.len = len;

		return &packet;
	}

	return NULL;
}
Esempio n. 9
0
File: Os.c Progetto: broonie/ohNet
int32_t OsNetworkReceiveFrom(THandle aHandle, uint8_t* aBuffer, uint32_t aBytes, TIpAddress* aAddress, uint16_t* aPort)
{
    int32_t received;
    OsNetworkHandle* handle = (OsNetworkHandle*)aHandle;
    struct sockaddr_in addr;
    int len = sizeof(addr);
    WSAEVENT event;
    HANDLE handles[2];
    DWORD ret;

    if (SocketInterrupted(handle)) {
        return -1;
    }

    sockaddrFromEndpoint(&addr, 0, 0);

    event = WSACreateEvent();
    if (NULL == event) {
        return -1;
    }
    if (0 != WSAEventSelect(handle->iSocket, event, FD_READ|FD_CLOSE)) {
        WSACloseEvent(event);
        return -1;
    }

    received = recvfrom(handle->iSocket, (char*)aBuffer, aBytes, 0, (struct sockaddr*)&addr, &len);
    if (SOCKET_ERROR==received && WSAEWOULDBLOCK==WSAGetLastError()) {
        handles[0] = event;
        handles[1] = handle->iEvent;
        ret = WSAWaitForMultipleEvents(2, &handles[0], FALSE, INFINITE, FALSE);
        if (WAIT_OBJECT_0 == ret) {
            received = recvfrom(handle->iSocket, (char*)aBuffer, aBytes, 0, (struct sockaddr*)&addr, &len);
        }
    }

    SetSocketBlocking(handle->iSocket);
    WSACloseEvent(event);
    *aAddress = addr.sin_addr.s_addr;
    *aPort = SwapEndian16(addr.sin_port);
    return received;
}
Esempio n. 10
0
File: Os.c Progetto: broonie/ohNet
DWORD interfaceChangeThread(LPVOID aArg)
{
    InterfaceChangeObserver* obs = (InterfaceChangeObserver*)aArg;
    while (obs->iShutdown == 0) {
        DWORD ret = WAIT_FAILED;
        DWORD bytes;
        if (SOCKET_ERROR == WSAIoctl(obs->iSocket, SIO_ADDRESS_LIST_CHANGE,
                                       NULL, 0, NULL, 0, &bytes, NULL, NULL)
            && WSAEWOULDBLOCK == WSAGetLastError()) {
            HANDLE handles[2];
            handles[0] = obs->iEvent;
            handles[1] = obs->iShutdownEvent;
            ret = WSAWaitForMultipleEvents(2, &handles[0], FALSE, INFINITE, FALSE);
        }
        if (WAIT_OBJECT_0 == ret) {
            (obs->iCallback)(obs->iArg);
            (void)WSAResetEvent(obs->iEvent);
        }
    }
    (void)ReleaseSemaphore(obs->iSem, 1, NULL);
    return 0;
}
Esempio n. 11
0
/*------------------------------------------------------------------------------------------------------------------
-- FUNCTION: ServerRoutine
-- DATE:	14/04/16
-- REVISIONS:	(V1.0)
-- DESIGNER:	Martin Minkov
-- PROGRAMMER:  Martin Minkov
-- INTERFACE:	void CALLBACK ServerRoutine(DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD InFlags)
--
--
-- RETURNS: VOID
-- NOTES: The completion routine used for UDP receiving. Constantly pushes valid data received into the circ buff
            so it can be used to play audio later.
----------------------------------------------------------------------------------------------------------------------*/
void CALLBACK ServerRoutine(DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD InFlags)
{
    DWORD RecvBytes = 0, Index;
    DWORD Flags = 0;
    WSAEVENT			EventArray[1] = { 0 };
    WSAEVENT			acceptEvent;

    // Reference the WSAOVERLAPPED structure as a SOCKET_INFORMATION structure
    LPSOCKET_INFORMATION SOCKINFO = (LPSOCKET_INFORMATION)Overlapped;
    initSockInfo(SOCKINFO, SOCKINFO->Buffer, SOCKINFO->server);

    if (Error != 0)
    {
        qDebug() << "I/O operation failed with value" + Error;
        printf("%d", Error);
        fflush(stdout);
        GlobalFree(SOCKINFO);
        SetEvent(streamStop);
        return;
    }
    if ((acceptEvent = WSACreateEvent()) == WSA_INVALID_EVENT)
    {
        qDebug() <<"WSACreateEvent() failed";
        GlobalFree(SOCKINFO);
        return;
    }

    Index = WSAWaitForMultipleEvents(1, EventArray, FALSE, 10000000, TRUE);

    if (Index == WSA_WAIT_TIMEOUT)
    {
        qDebug() <<"Timeout in UDP Server";
        GlobalFree(SOCKINFO);
        return;
    }
    receiveUDP(SOCKINFO, streamServer, BytesTransferred, Flags);
    cData.push(SOCKINFO->Buffer, 60000);
}
Esempio n. 12
0
int poll(struct pollfd *pollfds, nfds_t nfds, int timeout) {
    SOCKET *fds;
    HANDLE *hEvents;
    DWORD n;
    
    fds = (SOCKET *)alloca(sizeof(SOCKET) * nfds);
    hEvents = (HANDLE *)alloca(sizeof(HANDLE) * nfds);
    if (init(pollfds, nfds, fds, hEvents) < 0) {
        clean(nfds, fds, hEvents);
        return -1;
    }
    
    n = WSAWaitForMultipleEvents(nfds, hEvents, FALSE, timeout, FALSE);
    if (n == WSA_WAIT_FAILED) {
        clean(nfds, fds, hEvents);
        return -1;
    } else if (n == WSA_WAIT_TIMEOUT) {
        clean(nfds, fds, hEvents);
        return 0;
    } else {
        SOCKET fd;
        HANDLE hEvent;
        WSANETWORKEVENTS events;
        
        n -= WSA_WAIT_EVENT_0;
        fd = fds[n];
        hEvent = hEvents[n];
        
        if (WSAEnumNetworkEvents(fd, hEvent, &events) < 0) {
            clean(nfds, fds, hEvents);
            return -1;
        }
        
        pollfds[n].revents = (short) events.lNetworkEvents;
        clean(nfds, fds, hEvents);
        return n + 1;
    }
}
Esempio n. 13
0
static DirectResult
WaitForData( VoodooLink *link,
             int         timeout_ms )
{
     Link  *l = link->priv;
     DWORD  wait_result;

     WSAEventSelect( l->socket, l->event, FD_READ );

     wait_result = WSAWaitForMultipleEvents( 1, &l->event, FALSE, timeout_ms, FALSE );
     switch (wait_result) {
          case WSA_WAIT_EVENT_0:
               return DR_OK;

          case WSA_WAIT_TIMEOUT:
               return DR_TIMEOUT;

          default:
               D_ERROR( "Voodoo/Link: WaitForMultipleObjects() failed!\n" );
     }

     return DR_FAILURE;
}
Esempio n. 14
0
DWORD
HXWSAEventWaiter::HelperThread::Live()
{
    while(1)
    {
	/*
	 * Wait until it is time to start waiting.
	 */
	WaitForSingleObjectEx(m_hGoAheadAndWait, INFINITE,
	    FALSE);

	/*
	 * Are we supposed to be exiting?
	 */
	if(m_bPleaseDieNow)
	{
	    return 0;
	}
	/*
	 * Wait on what we are supposed to wait on.
	 */
	m_dwRetVal =
	    WSAWaitForMultipleEvents(m_dwNumEvents,
	    m_pEvents, FALSE, m_dwTimeout, FALSE);

	/*
	 * Reset our state for waiting again.
	 */
	ResetEvent(m_hGoAheadAndWait);
	/*
	 * Raise our hand and say we are done.
	 */
	SetEvent(m_hIAmDone);

    }
    return 0;
}
Esempio n. 15
0
void ListenerImpl::doListen()
{
    HANDLE			hWaits[2];
    hWaits[0]		= hKillEvent;
    hWaits[1]		= hSocketEvent;


    WSANETWORKEVENTS events;
    while(true)
    {
        // Wait for either the kill event or  an accept event :
        DWORD dwRet = WSAWaitForMultipleEvents(2, hWaits, FALSE, INFINITE, FALSE);

        //If kill event then quit loop :
        if (dwRet == WAIT_OBJECT_0)
        {
            break;
        }

        int nRet = WSAEnumNetworkEvents(hSocket, hSocketEvent, &events);
        if (nRet == SOCKET_ERROR)
        {
            //Error
            break;
        }

        //Deal with the new incoming connection
        if ((events.lNetworkEvents & FD_ACCEPT) && (events.iErrorCode[FD_ACCEPT_BIT] == 0))
        {
            if(!acceptConnectionRequest())
                break;
        }
        else
            break;
    }
}
Esempio n. 16
0
////////////////////////////////////////////////////////////////////////////////
//	函数名:INT RecvFrom(
//				SOCKET hSocket,
//				struct sockaddr * pFrom,
//				INT nFromlen,
//				CHAR *pszBuffer,
//				INT nBufferSize,
//				DWORD dwTimeout )
//	用  途:接收数据报
//	对全局变量的影响:无
//	参  数:
//		hSocket     : 套接字
//		pFrom       : 数据报的源地址
//		nFromlen    : 地址长度
//		pszBuffer   : 数据缓冲区
//		nBufferSize : 缓冲区大小
//		dwTimeout   : 超时
//	返回值:INT
////////////////////////////////////////////////////////////////////////////////
INT CBufSocket::RecvFrom(SOCKET hSocket, struct sockaddr * pFrom, INT nFromlen,CHAR *pszBuffer, INT nBufferSize, DWORD dwTimeout)
{
    HANDLE hReadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (hReadEvent == NULL)
    {
        SetLastError((INT)GetLastError() );
        return (SOCKET_ERROR);
    }

    DWORD		dwRecvBytes = 0,
                dwFlags		= 0;
    WSABUF		WSABuff;

    ZeroMemory(&WSABuff,sizeof(WSABUF));
    WSABuff.len = nBufferSize;
    WSABuff.buf = pszBuffer;

    for (;;)
    {
        // 注册FD_READ事件
        if( WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, FD_READ) == SOCKET_ERROR)
        {
            CloseHandle(hReadEvent);
            SetLastError(  WSAGetLastError() );
            return (SOCKET_FAIL);
        }
        DWORD dwWaitResult = WSAWaitForMultipleEvents(1, &hReadEvent, TRUE,	dwTimeout, TRUE);

        if( dwWaitResult != WSA_WAIT_EVENT_0 )
        {
            // 注销事件
            WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);
            CloseHandle(hReadEvent);
            SetLastError( WSAGetLastError());
            return (SOCKET_FAIL);
        }

        //////////////////////////////////////////////////////////////
        ///	注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该
        ///			进一步检查网络是否发生错误
        ///////////////////////////////////////////////////////////////
        WSANETWORKEVENTS NetEvent;
        if(WSAEnumNetworkEvents(hSocket,(WSAEVENT)hReadEvent,&NetEvent) == SOCKET_ERROR)
        {
            // 注销事件
            WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);
            CloseHandle(hReadEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }
        if(NetEvent.iErrorCode[FD_READ_BIT] !=0 )	// 发生错误
        {
            // 注销事件
            WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);
            CloseHandle(hReadEvent);
            SetLastError(NetEvent.iErrorCode[FD_READ_BIT]);
            return (SOCKET_FAIL);
        }
        ////////////////////////////////////////////////////////////////
        // 注销事件
        WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);

        INT nAddrLen = nFromlen;
        if ( WSARecvFrom(hSocket, &WSABuff, 1, &dwRecvBytes, &dwFlags,pFrom, &nAddrLen, NULL, NULL) == SOCKET_SUCCESS )
            break;

        if ( WSAGetLastError() != WSAEWOULDBLOCK)
        {
            CloseHandle(hReadEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }

        ///////////////////////////////////////////////////////////////////////////
        //	睡眠一段时间
        //////////////////////////////////////////////////////////////////////////
        Sleep(DEFAULT_BLOCKED_SNDRCV_SLEEP);
    }
    CloseHandle(hReadEvent);
    return ((INT) dwRecvBytes);

}
Esempio n. 17
0
////////////////////////////////////////////////////////////////////////////////
//	函数名:SOCKET Accept(
//				struct sockaddr * pSocketAddr,
//				LPINT nAddrLen,
//				HANDLE hEndEvent,
//				DWORD dwTimeout /*= DEFAULT_ACCEPT_TIMEOUT*/ )
//	用  途:接受套接字连接(允许中断)
//	对全局变量的影响:无
//	参  数:
//		pSocketAddr : SOCKET地址
//		nAddrLen    : 地址长度
//		hEndEvent   : 结束监听事件
//		dwTimeout   : 超时
//	返回值:SOCKET
////////////////////////////////////////////////////////////////////////////////
SOCKET CBufSocket::Accept(struct sockaddr * pSocketAddr, LPINT nAddrLen,HANDLE hEndEvent,DWORD dwTimeout /*= DEFAULT_ACCEPT_TIMEOUT*/)
{
    if( hEndEvent == NULL)
        return Accept(pSocketAddr,nAddrLen,dwTimeout);

    HANDLE	hAcceptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (hAcceptEvent == NULL)
    {
        SetLastError( (INT)GetLastError() );
        return (INVALID_SOCKET);
    }

    WSAEVENT hEvent[2];
    hEvent[0] = (WSAEVENT)hAcceptEvent;
    hEvent[1] = (WSAEVENT)hEndEvent;

    // 注册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(2, hEvent, FALSE,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);
}
Esempio n. 18
0
	// 接收数据
	bool CCommunication::PendingReceive(DWORD dwlen)
	{
		ZeroMemory(m_pbBuffer, m_nBufferSize);

		WSABUF			wsabuf;
		WSAOVERLAPPED	over;
		DWORD			dwRecv = 0;
		DWORD           dwTotalRecv = 0;
		DWORD			dwFlags;
		DWORD           dwRet;
		BOOL			fPending;
		int				nRet;

		ZeroMemory(&over, sizeof(WSAOVERLAPPED));
		wsabuf.buf  = m_pbBuffer;
		wsabuf.len  = dwlen;
		over.hEvent = WSACreateEvent();
		if(over.hEvent == WSA_INVALID_EVENT)
		{
			CloseSocket();
			return false;
		}

		while(1)
		{
			dwFlags = 0;
			fPending = FALSE;
			// 接收数据
			nRet = WSARecv(m_WorkSocket, &wsabuf, 1, &dwRecv,	&dwFlags, &over, NULL);
  			if(nRet != 0)
			{
				if( WSAGetLastError() != WSA_IO_PENDING)
				{					
					WSACloseEvent(over.hEvent);
					CloseSocket();
					return false;
				}
				else
				{
					fPending = TRUE;
				}
			}
			else
			{
				fPending = TRUE;
			}

			// 接收I/O未结束
			if(fPending)
			{
				// 等待接收I/O操作完成
				dwRet = WSAWaitForMultipleEvents(1, &(over.hEvent), FALSE, m_nTimeOut*1000, FALSE);
				if(dwRet==WSA_WAIT_FAILED || dwRet==WAIT_TIMEOUT)
				{
					WSACloseEvent(over.hEvent);
					CloseSocket();
					return false;
				}

				WSAResetEvent(over.hEvent);

				// 判断重叠操作是否成功
				if(!WSAGetOverlappedResult(m_WorkSocket, &over, &dwRecv, FALSE, &dwFlags))
				{
					WSACloseEvent(over.hEvent);
					CloseSocket();
					return false;
				}
				else
				{
					if(dwRecv == 0)
					{
						WSACloseEvent(over.hEvent);
						CloseSocket();
						return false;
					}

					// 计算接收总字节数
					dwTotalRecv += dwRecv;
					wsabuf.len -= dwRecv;

					if(wsabuf.len <= 0)
					{
						break;
					}
					else
					{
						wsabuf.buf += dwRecv;
					}
				}
			}
		}//while(1) 接收未结束

		if(over.hEvent)
		{
			WSACloseEvent(over.hEvent);
		}
		return true;
	}
Esempio n. 19
0
	// 发送数据
	bool CCommunication::PendingSend(DWORD dwlen)
	{
		WSABUF			wsabuf;
		WSAOVERLAPPED	over;
		DWORD			dwSend;
		DWORD           dwTotalSend = 0;
		DWORD			dwFlags;
		DWORD			dwRet;
		BOOL			fPending;

		ZeroMemory(&over, sizeof(WSAOVERLAPPED));
		wsabuf.buf  = m_pbBuffer;
		wsabuf.len  = dwlen;
		over.hEvent = WSACreateEvent();
		if (over.hEvent == WSA_INVALID_EVENT)
		{
#ifdef _ZZYDEBUG
					GC_TRACE("Error5");
#endif
			CloseSocket();
			return false;
		}

		while(1)
		{
			fPending = FALSE;
			// 发送数据
			int nRet = WSASend(m_WorkSocket, &wsabuf, 1, &dwSend, 0, &over, NULL);
			if (nRet != 0)
			{
				if (WSAGetLastError() != WSA_IO_PENDING)
				{
#ifdef _ZZYDEBUG
					GC_TRACE("Error4:%d",WSAGetLastError());
#endif
					WSACloseEvent(over.hEvent);
					CloseSocket();
					return false;
				}
				else
				{
					fPending = TRUE;
				}
			}
			else
			{
				fPending = TRUE;
			}

			// 发送I/O操作未结束
			if (fPending)
			{
				// 等待发送I/O操作接束
				dwRet = WSAWaitForMultipleEvents(1, &(over.hEvent), FALSE, m_nTimeOut*1000, FALSE);
				if (dwRet==WSA_WAIT_FAILED || dwRet==WAIT_TIMEOUT)
				{
#ifdef _ZZYDEBUG
					if (dwRet==WSA_WAIT_FAILED)
						GC_TRACE("Error1");
					else
						GC_TRACE("Error6");

#endif
					WSACloseEvent(over.hEvent);
					CloseSocket();
					return false;
				}

				WSAResetEvent(over.hEvent);

				// 判断重叠操作是否成功
				if (!WSAGetOverlappedResult(m_WorkSocket,	&over, &dwSend,	FALSE, &dwFlags))
				{
#ifdef _ZZYDEBUG
					GC_TRACE("Error2");
#endif
					WSACloseEvent(over.hEvent);
					CloseSocket();
					return false;
				}
				else
				{
					if (dwSend == 0)
					{
#ifdef _ZZYDEBUG
					GC_TRACE("Error3");
#endif
						WSACloseEvent(over.hEvent);
						CloseSocket();
						return false;
					}

					// 计算剩余发送字节数
					wsabuf.len -= dwSend;
					dwTotalSend += dwSend;

					if(wsabuf.len <= 0)
					{
						break;
					}
					else
					{
						wsabuf.buf += dwSend;
					}
				}
			}
		}//while (1) 发送未结束

		// 发送完成
		if(over.hEvent)
		{
			WSACloseEvent(over.hEvent);
		}
		return true;
	}
unsigned int __stdcall CxServerSocketTCP::WorkerThread( LPVOID lpParam )
{
	char * pRecvBuffer = NULL;
	ServerThreadContext* pContext = (ServerThreadContext*) lpParam;
	CxServerSocketTCP *pThis = (CxServerSocketTCP *)pContext->pThis;

	XTRACE( _T("Starting thread [%p]0x%x\r\n"), pContext, pContext->hThread );

	if ( !pContext->bListen )
		pThis->OnClientConnected( pContext, pContext->strClientIP, pContext->nClientPort );

	const int nRecvBufferSize = pThis->m_nMaxRecvBufferSize;
	if ( !(pRecvBuffer = (char *)xmalloc(nRecvBufferSize)) ) 
		return 0;

	int nEventIndex;
	WSANETWORKEVENTS hNetworkEvents;
	BOOL bWork = TRUE;
	while ( bWork ) 
	{
		nEventIndex = WSAWaitForMultipleEvents( 2, pContext->hNetEvent, FALSE, 500, FALSE );

		nEventIndex -= WSA_WAIT_EVENT_0;

		for ( int ix=nEventIndex ; ix<2 ; ix++ )
		{
			nEventIndex = WSAWaitForMultipleEvents( 1, &pContext->hNetEvent[ix], TRUE, 0, FALSE );

			if ( (nEventIndex == WSA_WAIT_FAILED ) ) continue;
			else if ( (nEventIndex==WSA_WAIT_TIMEOUT) )
			{
			}
			else
			{
				if ( ix == 1 )
				{
					WSAEnumNetworkEvents( pContext->hSocket, pContext->hNetEvent[1], &hNetworkEvents );
					if ( hNetworkEvents.lNetworkEvents & FD_READ )
					{
						if ( hNetworkEvents.iErrorCode[FD_READ_BIT] != 0 )
						{
							XTRACE( _T("Socket Read Error![%p]\r\n"), pContext );
							break;
						}
						int nRecvBytes = recv( pContext->hSocket, pRecvBuffer, nRecvBufferSize, 0 );

						if ( nRecvBytes > 0 )
						{
							//XTRACE( _T("%d bytes received!\r\n"), nRecvBytes );
							pThis->ProcessBuffer( pContext, pRecvBuffer, nRecvBytes );
						}
						else
						{
							char szBye[3] = { 0, };
							send( pContext->hSocket, szBye, 3, 0 );
							shutdown( pContext->hSocket, SD_BOTH );
							closesocket( pContext->hSocket );
							XTRACE( _T("Closed socket handle [%p]%x\r\n"), pContext, pContext->hSocket );
							
							pContext->hSocket = INVALID_SOCKET;

							if ( pContext->bListen )
								pThis->OnStopServer();
							else
							{
								pThis->OnClientDisconnected( pContext->strClientIP, pContext->nClientPort );
								bWork = FALSE;
							}

						}
					}

					if ( hNetworkEvents.lNetworkEvents & FD_ACCEPT )
					{
						if ( hNetworkEvents.iErrorCode[FD_ACCEPT_BIT] != 0 )
						{
							XTRACE( _T("[%p] Accept Error!\r\n"), pContext );
						}

						SOCKADDR_IN addrinClient;
						int nAddrSize = sizeof(SOCKADDR_IN);
						SOCKET hClientSocket = ::accept( pContext->hSocket, reinterpret_cast<struct sockaddr *>(&addrinClient), &nAddrSize );

						if ( hClientSocket == INVALID_SOCKET )
						{
							XTRACE( _T("[%p] accept() failed: %d\r\n"), pContext, WSAGetLastError() );
							bWork = FALSE;
							break;
						}

						int nRet;
						int nMaxSendBufferSize = MAX_SEND_BUF_SIZE;
						int nMaxRecvBufferSize = MAX_RECV_BUF_SIZE;
						nRet = ::setsockopt( hClientSocket, SOL_SOCKET, SO_SNDBUF, (const char*)&nMaxSendBufferSize, sizeof(int) );
						nRet = ::setsockopt( hClientSocket, SOL_SOCKET, SO_RCVBUF, (const char*)&nMaxRecvBufferSize, sizeof(int) );

						int nLen = sizeof(int);
						nRet = ::getsockopt( hClientSocket, SOL_SOCKET, SO_SNDBUF, (char*)&nMaxSendBufferSize, &nLen );
						nLen = sizeof(int);
						nRet = ::getsockopt( hClientSocket, SOL_SOCKET, SO_RCVBUF, (char*)&nMaxRecvBufferSize, &nLen );

						CxString strClientIP;
						int nPort;

						TCHAR szClientAddr[50]={0,};
						DWORD dwSize = sizeof(szClientAddr);
						SOCKADDR* pClientSockAddr = (SOCKADDR*)&addrinClient;
						CxString strClientSockAddr;
						if ( WSAAddressToString( pClientSockAddr, sizeof(SOCKADDR), NULL, szClientAddr, &dwSize) != SOCKET_ERROR )
						{
							strClientSockAddr = szClientAddr;
						}

						int nColonPos = strClientSockAddr.ReverseFind( _T(':') );
						strClientIP = strClientSockAddr.Left( nColonPos );
						strClientSockAddr.Delete( 0, nColonPos+1 );

						nPort = _tcstol(strClientSockAddr, NULL, 10);

						ServerThreadContext* pThreadContext = new ServerThreadContext;

						pThreadContext->hSocket = hClientSocket;
						pThreadContext->hThread = NULL;
						pThreadContext->pThis = pThis;
						pThreadContext->hNetEvent[0] = pThis->m_hCleanupEvent;
						pThreadContext->hNetEvent[1] = WSA_INVALID_EVENT;
						pThreadContext->IoBuffer.Create( pThis->GetIOBufferSize() );
						pThreadContext->IoBuffer.Clear();
						pThreadContext->bListen = FALSE;
						pThreadContext->strClientIP = strClientIP;
						pThreadContext->nClientPort = nPort;
						pThreadContext->dwUserData = 0;

						pThreadContext->hNetEvent[1] = WSACreateEvent();
						if ( WSAEventSelect( pThreadContext->hSocket, pThreadContext->hNetEvent[1], FD_READ|FD_CLOSE ) == SOCKET_ERROR )
						{
							XTRACE( _T("WSAEventSelect() error\r\n") );
							break;
						}
						
						unsigned int nThreadID = 0;
						pThreadContext->hThread = (HANDLE)::_beginthreadex( NULL, 0, WorkerThread, pThreadContext, 0, &nThreadID );
						
						if ( pThreadContext->hThread == NULL )
						{
							delete pThreadContext;
							break;
						}

						CloseHandle( pThreadContext->hThread );
					}

					if ( hNetworkEvents.lNetworkEvents & FD_CLOSE ) // ¿¬°á Á¾·á
					{
						if ( hNetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0 )	
						{
							XTRACE( _T("Abnormal closed...!!!\r\n") );
						}
						else
						{
							WSACloseEvent( pContext->hNetEvent[1] );
							pContext->hNetEvent[1] = WSA_INVALID_EVENT;
						}

						char szBye[3] = { 0, };
						send( pContext->hSocket, szBye, 3, 0 );
						shutdown( pContext->hSocket, SD_BOTH );
						closesocket( pContext->hSocket );
						XTRACE( _T("Closed socket handle [%p]%x\r\n"), pContext, pContext->hSocket );

						pContext->hSocket = INVALID_SOCKET;

						if ( pContext->bListen )
							pThis->OnStopServer();
						else
						{
							pThis->OnClientDisconnected( pContext->strClientIP, pContext->nClientPort );
							bWork = FALSE;
						}
						break;
					}
				}
				else
				{
					bWork = FALSE;
					break;
				}
			}
		}
	}

	if ( pRecvBuffer )
		xfree(pRecvBuffer);

	XTRACE( _T("Exit thread [%p]0x%x\r\n"), pContext, pContext->hThread );

	if ( !pContext->bListen )
	{
		delete pContext;
	}

	_endthreadex(0);

	return 0;
}
Esempio n. 21
0
// 비동기 입출력 처리 함수
DWORD WINAPI WorkerThread(LPVOID arg)
{
	int retval;

	while(1){
		// 이벤트 객체 관찰
		DWORD index = WSAWaitForMultipleEvents(nTotalSockets,
			EventArray, FALSE, WSA_INFINITE, FALSE);
		if(index == WSA_WAIT_FAILED) continue;
		index -= WSA_WAIT_EVENT_0;
		WSAResetEvent(EventArray[index]);
		if(index == 0) continue;

		// 클라이언트 정보 얻기
		SOCKETINFO *ptr = SocketInfoArray[index];
		SOCKADDR_IN clientaddr;
		int addrlen = sizeof(clientaddr);
		getpeername(ptr->sock, (SOCKADDR *)&clientaddr, &addrlen);

		// 비동기 입출력 결과 확인
		DWORD cbTransferred, flags;
		retval = WSAGetOverlappedResult(ptr->sock, &ptr->overlapped,
			&cbTransferred, FALSE, &flags);
		if(retval == FALSE || cbTransferred == 0){
			RemoveSocketInfo(index);
			printf("[TCP 서버] 클라이언트 종료: IP 주소=%s, 포트 번호=%d\n",
				inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
			continue;
		}

		// 데이터 전송량 갱신
		if(ptr->recvbytes == 0){
			ptr->recvbytes = cbTransferred;
			ptr->sendbytes = 0;
			// 받은 데이터 출력
			ptr->buf[ptr->recvbytes] = '\0';
			printf("[TCP/%s:%d] %s\n", inet_ntoa(clientaddr.sin_addr),
				ntohs(clientaddr.sin_port), ptr->buf);
		}
		else{
			ptr->sendbytes += cbTransferred;
		}

		if(ptr->recvbytes > ptr->sendbytes){
			// 데이터 보내기
			ZeroMemory(&ptr->overlapped, sizeof(ptr->overlapped));
			ptr->overlapped.hEvent = EventArray[index];
			ptr->wsabuf.buf = ptr->buf + ptr->sendbytes;
			ptr->wsabuf.len = ptr->recvbytes - ptr->sendbytes;

			DWORD sendbytes;
			retval = WSASend(ptr->sock, &ptr->wsabuf, 1, &sendbytes,
				0, &ptr->overlapped, NULL);
			if(retval == SOCKET_ERROR){
				if(WSAGetLastError() != WSA_IO_PENDING){
					err_display("WSASend()");
				}
				continue;
			}
		}
		else{
			ptr->recvbytes = 0;

			// 데이터 받기
			ZeroMemory(&ptr->overlapped, sizeof(ptr->overlapped));
			ptr->overlapped.hEvent = EventArray[index];
			ptr->wsabuf.buf = ptr->buf;
			ptr->wsabuf.len = BUFSIZE;

			DWORD recvbytes;
			flags = 0;
			retval = WSARecv(ptr->sock, &ptr->wsabuf, 1, &recvbytes,
				&flags, &ptr->overlapped, NULL);
			if(retval == SOCKET_ERROR){
				if(WSAGetLastError() != WSA_IO_PENDING){
					err_display("WSARecv()");
				}
				continue;
			}
		}
	}
}
Esempio n. 22
0
LWS_EXTERN int
_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
{
	struct lws_context_per_thread *pt;
	WSANETWORKEVENTS networkevents;
	struct lws_pollfd *pfd;
	struct lws *wsi;
	unsigned int i;
	DWORD ev;
	int n;

	/* stay dead once we are dead */
	if (context == NULL || !context->vhost_list)
		return 1;

	pt = &context->pt[tsi];

	if (!pt->service_tid_detected) {
		struct lws _lws;

		memset(&_lws, 0, sizeof(_lws));
		_lws.context = context;

		pt->service_tid = context->vhost_list->
			protocols[0].callback(&_lws, LWS_CALLBACK_GET_THREAD_ID,
						  NULL, NULL, 0);
		pt->service_tid_detected = 1;
	}

	if (timeout_ms < 0) {
		if (lws_service_flag_pending(context, tsi)) {
			/* any socket with events to service? */
			for (n = 0; n < (int)pt->fds_count; n++) {
				int m;
				if (!pt->fds[n].revents)
					continue;

				m = lws_service_fd_tsi(context, &pt->fds[n], tsi);
				if (m < 0)
					return -1;
				/* if something closed, retry this slot */
				if (m)
					n--;
			}
		}
		return 0;
	}

	if (context->event_loop_ops->run_pt)
		context->event_loop_ops->run_pt(context, tsi);

	for (i = 0; i < pt->fds_count; ++i) {
		pfd = &pt->fds[i];

		if (!(pfd->events & LWS_POLLOUT))
			continue;

		wsi = wsi_from_fd(context, pfd->fd);
		if (!wsi || wsi->listener)
			continue;
		if (wsi->sock_send_blocking)
			continue;
		pfd->revents = LWS_POLLOUT;
		n = lws_service_fd(context, pfd);
		if (n < 0)
			return -1;

		/*
		 * Force WSAWaitForMultipleEvents() to check events
		 * and then return immediately.
		 */
		timeout_ms = 0;

		/* if something closed, retry this slot */
		if (n)
			i--;
	}

	/*
	 * is there anybody with pending stuff that needs service forcing?
	 */
	if (!lws_service_adjust_timeout(context, 1, tsi)) {
		/* -1 timeout means just do forced service */
		_lws_plat_service_tsi(context, -1, pt->tid);
		/* still somebody left who wants forced service? */
		if (!lws_service_adjust_timeout(context, 1, pt->tid))
			/* yes... come back again quickly */
			timeout_ms = 0;
	}

	if (timeout_ms) {
		lws_usec_t t;

		lws_pt_lock(pt, __func__);
		/* don't stay in poll wait longer than next hr timeout */
		t =  __lws_hrtimer_service(pt);

		if ((lws_usec_t)timeout_ms * 1000 > t)
			timeout_ms = (int)(t / 1000);
		lws_pt_unlock(pt);
	}

	for (n = 0; n < (int)pt->fds_count; n++)
		WSAEventSelect(pt->fds[n].fd, pt->events,
		       FD_READ | (!!(pt->fds[n].events & LWS_POLLOUT) * FD_WRITE) |
		       FD_OOB | FD_ACCEPT |
		       FD_CONNECT | FD_CLOSE | FD_QOS |
		       FD_ROUTING_INTERFACE_CHANGE |
		       FD_ADDRESS_LIST_CHANGE);

	ev = WSAWaitForMultipleEvents(1, &pt->events, FALSE, timeout_ms, FALSE);
	if (ev == WSA_WAIT_EVENT_0) {
		unsigned int eIdx;

#if defined(LWS_WITH_TLS)
		if (pt->context->tls_ops &&
		    pt->context->tls_ops->fake_POLLIN_for_buffered)
			pt->context->tls_ops->fake_POLLIN_for_buffered(pt);
#endif

		for (eIdx = 0; eIdx < pt->fds_count; ++eIdx) {
			unsigned int err;

			if (WSAEnumNetworkEvents(pt->fds[eIdx].fd, pt->events,
					&networkevents) == SOCKET_ERROR) {
				lwsl_err("WSAEnumNetworkEvents() failed "
					 "with error %d\n", LWS_ERRNO);
				return -1;
			}

			if (!networkevents.lNetworkEvents)
				networkevents.lNetworkEvents = LWS_POLLOUT;

			pfd = &pt->fds[eIdx];
			pfd->revents = (short)networkevents.lNetworkEvents;

			err = networkevents.iErrorCode[FD_CONNECT_BIT];

			if ((networkevents.lNetworkEvents & FD_CONNECT) &&
			     err && err != LWS_EALREADY &&
			     err != LWS_EINPROGRESS && err != LWS_EWOULDBLOCK &&
			     err != WSAEINVAL) {
				lwsl_debug("Unable to connect errno=%d\n", err);
				pfd->revents |= LWS_POLLHUP;
			}

			if (pfd->revents & LWS_POLLOUT) {
				wsi = wsi_from_fd(context, pfd->fd);
				if (wsi)
					wsi->sock_send_blocking = 0;
			}
			 /* if something closed, retry this slot */
			if (pfd->revents & LWS_POLLHUP)
				--eIdx;

			if (pfd->revents) {
				recv(pfd->fd, NULL, 0, 0);
				lws_service_fd_tsi(context, pfd, tsi);
			}
		}
	} else if (ev == WSA_WAIT_TIMEOUT) {
		lws_service_fd(context, NULL);
	} else if (ev == WSA_WAIT_FAILED)
		return 0;

	return 0;
}
Esempio n. 23
0
static
gpointer
receiver_thread (
	gpointer	data
	)
{
	pgm_sock_t* rx_sock = (pgm_sock_t*)data;
	const long iov_len = 20;
	const long ev_len  = 1;
	struct pgm_msgv_t msgv[iov_len];

#ifdef CONFIG_HAVE_EPOLL
	struct epoll_event events[ev_len];	/* wait for maximum 1 event */
	const int efd = epoll_create (IP_MAX_MEMBERSHIPS);
	if (efd < 0) {
		g_error ("epoll_create failed errno %i: \"%s\"", errno, strerror(errno));
		g_main_loop_quit (g_loop);
		return NULL;
	}

	if (pgm_epoll_ctl (rx_sock, efd, EPOLL_CTL_ADD, EPOLLIN) < 0)
	{
		g_error ("pgm_epoll_ctl failed errno %i: \"%s\"", errno, strerror(errno));
		g_main_loop_quit (g_loop);
		return NULL;
	}
	struct epoll_event event;
	event.events = EPOLLIN;
	event.data.fd = g_quit_pipe[0];
	if (epoll_ctl (efd, EPOLL_CTL_ADD, g_quit_pipe[0], &event) < 0)
	{
		g_error ("epoll_ctl failed errno %i: \"%s\"", errno, strerror(errno));
		g_main_loop_quit (g_loop);
		return NULL;
	}
#elif defined(CONFIG_HAVE_POLL)
	int n_fds = 2;
	struct pollfd fds[ 1 + n_fds ];
#elif defined(G_OS_UNIX) /* HAVE_SELECT */
	int n_fds;
	fd_set readfds;
#else /* G_OS_WIN32 */
	SOCKET recv_sock, pending_sock;
	DWORD cEvents = PGM_RECV_SOCKET_READ_COUNT + 1;
	WSAEVENT waitEvents[ PGM_RECV_SOCKET_READ_COUNT + 1 ];
	socklen_t socklen = sizeof (SOCKET);

	waitEvents[0] = g_quit_event;
	waitEvents[1] = WSACreateEvent ();
	pgm_getsockopt (rx_sock, IPPROTO_PGM, PGM_RECV_SOCK, &recv_sock, &socklen);
	WSAEventSelect (recv_sock, waitEvents[1], FD_READ);
	waitEvents[2] = WSACreateEvent ();
	pgm_getsockopt (rx_sock, IPPROTO_PGM, PGM_PENDING_SOCK, &pending_sock, &socklen);
	WSAEventSelect (pending_sock, waitEvents[2], FD_READ);
#endif /* !CONFIG_HAVE_EPOLL */

	do {
		struct timeval tv;
#ifndef _WIN32
		int timeout;
#else
		DWORD dwTimeout, dwEvents;
#endif
		size_t len;
		pgm_error_t* pgm_err = NULL;
		const int status = pgm_recvmsgv (rx_sock,
					         msgv,
					         G_N_ELEMENTS(msgv),
					         0,
					         &len,
					         &pgm_err);
		switch (status) {
		case PGM_IO_STATUS_NORMAL:
			on_msgv (msgv, len);
			break;
		case PGM_IO_STATUS_TIMER_PENDING:
			{
				socklen_t optlen = sizeof (tv);
				pgm_getsockopt (rx_sock, IPPROTO_PGM, PGM_TIME_REMAIN, &tv, &optlen);
			}
			goto block;
		case PGM_IO_STATUS_RATE_LIMITED:
			{
				socklen_t optlen = sizeof (tv);
				pgm_getsockopt (rx_sock, IPPROTO_PGM, PGM_RATE_REMAIN, &tv, &optlen);
			}
/* fall through */
		case PGM_IO_STATUS_WOULD_BLOCK:
block:
#ifdef CONFIG_HAVE_EPOLL
			timeout = PGM_IO_STATUS_WOULD_BLOCK == status ? -1 : ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
			epoll_wait (efd, events, G_N_ELEMENTS(events), timeout /* ms */);
#elif defined(CONFIG_HAVE_POLL)
			timeout = PGM_IO_STATUS_WOULD_BLOCK == status ? -1 : ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
			memset (fds, 0, sizeof(fds));
			fds[0].fd = g_quit_pipe[0];
			fds[0].events = POLLIN;
			pgm_poll_info (rx_sock, &fds[1], &n_fds, POLLIN);
			poll (fds, 1 + n_fds, timeout /* ms */);
#elif defined(G_OS_UNIX) /* HAVE_SELECT */
			FD_ZERO(&readfds);
			FD_SET(g_quit_pipe[0], &readfds);
			n_fds = g_quit_pipe[0] + 1;
			pgm_select_info (rx_sock, &readfds, NULL, &n_fds);
			select (n_fds, &readfds, NULL, NULL, PGM_IO_STATUS_RATE_LIMITED == status ? &tv : NULL);
#else /* G_OS_WIN32 */
			dwTimeout = PGM_IO_STATUS_WOULD_BLOCK == status ? WSA_INFINITE : ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
			dwEvents = WSAWaitForMultipleEvents (cEvents, waitEvents, FALSE, dwTimeout, FALSE);
			switch (dwEvents) {
			case WSA_WAIT_EVENT_0+1: WSAResetEvent (waitEvents[1]); break;
			case WSA_WAIT_EVENT_0+2: WSAResetEvent (waitEvents[2]); break;
			default: break;
			}
#endif /* !CONFIG_HAVE_EPOLL */
			break;

		default:
			if (pgm_err) {
				g_warning ("%s", pgm_err->message);
				pgm_error_free (pgm_err);
				pgm_err = NULL;
			}
			if (PGM_IO_STATUS_ERROR == status)
				break;
		}
	} while (!g_quit);

#ifdef CONFIG_HAVE_EPOLL
	close (efd);
#elif defined(G_OS_WIN32)
	WSACloseEvent (waitEvents[1]);
	WSACloseEvent (waitEvents[2]);
#  if (__STDC_VERSION__ < 199901L)
	g_free (waitHandles);
#  endif
#endif
	return NULL;
}
DWORD WINAPI WorkerThreadCallback(LPVOID lpParameter)
{
    DWORD Flags;
    LPSOCKET_INFORMATION_CALLBACK SocketInfo;
    WSAEVENT EventArray[1];
    DWORD Index;
    DWORD RecvBytes;

    // Save the accept event in the event array
    EventArray[0] = (WSAEVENT) lpParameter;
 
    while(TRUE)
    {
        // Wait for accept() to signal an event and also process WorkerRoutine() returns
        while(TRUE)
        {
            Index = WSAWaitForMultipleEvents(1, EventArray, FALSE, WSA_INFINITE, TRUE);
            if (Index == WSA_WAIT_FAILED)
            {
                printf("WSAWaitForMultipleEvents() failed with error %d\n", WSAGetLastError());
                return FALSE;
            }
            else
                printf("WSAWaitForMultipleEvents() should be OK!\n");
 
            if (Index != WAIT_IO_COMPLETION)
            {
                // An accept() call event is ready - break the wait loop
                break;
            }
        }
 
		/* The WSAResetEvent function resets the state 
		 * of the specified event object to nonsignaled. */
        WSAResetEvent(EventArray[Index - WSA_WAIT_EVENT_0]);
        // Create a socket information structure to associate with the accepted socket
        if ((SocketInfo = (LPSOCKET_INFORMATION_CALLBACK) GlobalAlloc(GPTR, sizeof(SOCKET_INFORMATION_CALLBACK))) == NULL)
        {
            printf("GlobalAlloc() failed with error %d\n", GetLastError());
            return FALSE;
        }
        else
            printf("GlobalAlloc() for SOCKET_INFORMATION is OK!\n");
 
        // Fill in the details of our accepted socket
        SocketInfo->Socket = AcceptSocketCallback;
        ZeroMemory(&(SocketInfo->Overlapped), sizeof(WSAOVERLAPPED));
        SocketInfo->BytesSEND = 0;
        SocketInfo->BytesRECV = 0;
        SocketInfo->DataBuf.len = DEFAULT_BUFLEN;
        SocketInfo->DataBuf.buf = SocketInfo->Buffer;
 

        Flags = 0;
        if (WSARecv(SocketInfo->Socket, 
			      &(SocketInfo->DataBuf), 
				  1, 
				  &RecvBytes, 
				  &Flags,
                  &(SocketInfo->Overlapped), 
				  WorkerRoutineCallback) == SOCKET_ERROR)
        {
            if (WSAGetLastError() != WSA_IO_PENDING)
            {
                printf("WSARecv() failed with error %d\n", WSAGetLastError());
                return FALSE;
            }
        }
        else
            printf("WSARecv() is OK!\n");

        printf("Socket %d got connected...\n", AcceptSocketCallback);
    }
    return TRUE;
}
Esempio n. 25
0
////////////////////////////////////////////////////////////////////////////////
//	函数名:INT SendData(
//				SOCKET hSocket,
//				LPCSTR pszBuffer,
//				INT nBufferSize,
//				DWORD dwTimeout )
//	用  途:发送数据
//	对全局变量的影响:无
//	参  数:
//		hSocket     : 待发送的套接字
//		pszBuffer   : 发送数据缓冲区
//		nBufferSize : 缓冲区大小
//		dwTimeout   : 发送超时
//	返回值:INT
//		>=0			: 成功,已成功发送的字节数
//		<0			: 失败(SOCKET_FAIL:-1)
////////////////////////////////////////////////////////////////////////////////
INT CBufSocket::SendData(SOCKET hSocket, LPCSTR pszBuffer, INT nBufferSize, DWORD dwTimeout)
{
    HANDLE	hWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    if (hWriteEvent == NULL)
    {
        SetLastError( (INT)GetLastError() );
        return (SOCKET_FAIL);
    }

    INT nSendBytes = 0;

    for (;;)
    {
        ////////////////////////////////////////////////////////////////
        // 发送数据成功
        if ((nSendBytes = SendOnce(hSocket, pszBuffer, nBufferSize)) >= 0)
            break;

        INT nErrorCode = -nSendBytes;

        if (nErrorCode != WSAEWOULDBLOCK)
        {
            CloseHandle(hWriteEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }


        ///////////////////////////////////////////////////////////////////////////////
        //  睡眠一段时间
        ///////////////////////////////////////////////////////////////////////////////
        Sleep(DEFAULT_BLOCKED_SNDRCV_SLEEP);

        // 注册FD_WRITE | FD_CLOSE 事件
        if( WSAEventSelect(hSocket, (WSAEVENT) hWriteEvent, FD_WRITE|FD_CLOSE) == SOCKET_ERROR)
        {
            CloseHandle(hWriteEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }

        // 等待事件发生
        DWORD dwWaitResult = WSAWaitForMultipleEvents(1, &hWriteEvent, TRUE,dwTimeout, TRUE);

        if (dwWaitResult != WSA_WAIT_EVENT_0)
        {
            // 清除网络事件
            WSAEventSelect(hSocket, (WSAEVENT) hWriteEvent, 0);
            CloseHandle(hWriteEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }

        //////////////////////////////////////////////////////////////
        ///	注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该
        ///			进一步检查网络是否发生错误
        ///////////////////////////////////////////////////////////////
        WSANETWORKEVENTS NetEvent;
        if(WSAEnumNetworkEvents(hSocket,(WSAEVENT)hWriteEvent,&NetEvent) == SOCKET_ERROR)
        {
            // 清除网络事件
            WSAEventSelect(hSocket, (WSAEVENT) hWriteEvent, 0);
            CloseHandle(hWriteEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }
        if( ( NetEvent.lNetworkEvents == FD_CLOSE ) ||
                ( NetEvent.lNetworkEvents == FD_WRITE   &&
                  NetEvent.iErrorCode[FD_WRITE_BIT] !=0 ) )	// 发生错误
        {
            // 清除网络事件
            WSAEventSelect(hSocket, (WSAEVENT) hWriteEvent, 0);
            CloseHandle(hWriteEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }
        // 清除网络事件
        WSAEventSelect(hSocket, (WSAEVENT) hWriteEvent, 0);
    }

    CloseHandle(hWriteEvent);
    return (nSendBytes);
}
Esempio n. 26
0
////////////////////////////////////////////////////////////////////////////////
//	函数名:INT SendTo(
//				SOCKET hSocket,
//				CONST struct sockaddr * pTo,
//				INT nToLen,
//				LPCSTR pszBuffer,
//				INT nBufferSize,
//				DWORD dwTimeout )
//	用  途:发送数据报
//	对全局变量的影响:无
//	参  数:
//		hSocket     : 套接字
//		pTo         : 数据报的目的地址
//		nToLen      : 地址长度
//		pszBuffer   : 缓冲区
//		nBufferSize : 缓冲区大小
//		dwTimeout   : 超时
//	返回值:INT
////////////////////////////////////////////////////////////////////////////////
INT CBufSocket::SendTo(SOCKET hSocket, CONST struct sockaddr * pTo,INT nToLen,LPCSTR pszBuffer, INT nBufferSize, DWORD dwTimeout)
{
    HANDLE hWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (hWriteEvent == NULL)
    {
        SetLastError( (INT)GetLastError() );
        return (SOCKET_FAIL);
    }

    DWORD	dwSendBytes = 0,
            dwFlags		= 0;
    WSABUF	WSABuff;

    ZeroMemory(&WSABuff,sizeof(WSABUF));
    WSABuff.len = nBufferSize;
    WSABuff.buf = (CHAR *) pszBuffer;

    for (;;)
    {
        if (WSASendTo( hSocket, &WSABuff, 1, &dwSendBytes, dwFlags,pTo, nToLen, NULL, NULL) == SOCKET_SUCCESS)
            break;

        if (WSAGetLastError() != WSAEWOULDBLOCK)
        {
            CloseHandle(hWriteEvent);
            SetLastError(  WSAGetLastError() );
            return (SOCKET_FAIL);
        }

        //////////////////////////////////////////////////////////////////////////
        //	睡眠一段时间
        /////////////////////////////////////////////////////////////////////////
        Sleep(DEFAULT_BLOCKED_SNDRCV_SLEEP);

        // 注册FD_WRITE事件
        if( WSAEventSelect(hSocket, (WSAEVENT) hWriteEvent, FD_WRITE) == SOCKET_ERROR)
        {
            CloseHandle(hWriteEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }
        DWORD dwWaitResult = WSAWaitForMultipleEvents(1, &hWriteEvent, TRUE,dwTimeout, TRUE);

        if( dwWaitResult != WSA_WAIT_EVENT_0 )
        {
            // 注销事件
            WSAEventSelect(hSocket, (WSAEVENT) hWriteEvent, 0);
            CloseHandle(hWriteEvent);
            SetLastError(  WSAGetLastError() );
            return (SOCKET_FAIL);
        }

        //////////////////////////////////////////////////////////////
        ///	注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该
        ///			进一步检查网络是否发生错误
        ///////////////////////////////////////////////////////////////
        WSANETWORKEVENTS NetEvent;
        if(WSAEnumNetworkEvents(hSocket,(WSAEVENT)hWriteEvent,&NetEvent) == SOCKET_ERROR)
        {
            // 注销事件
            WSAEventSelect(hSocket, (WSAEVENT) hWriteEvent, 0);
            CloseHandle(hWriteEvent);
            SetLastError(  WSAGetLastError() );
            return (SOCKET_FAIL);
        }
        if(NetEvent.iErrorCode[FD_WRITE_BIT] !=0 )	// 发生错误
        {
            // 注销事件
            WSAEventSelect(hSocket, (WSAEVENT) hWriteEvent, 0);
            CloseHandle(hWriteEvent);
            SetLastError(NetEvent.iErrorCode[FD_WRITE_BIT]);
            return (SOCKET_FAIL);
        }
        ////////////////////////////////////////////////////////////////
        // 注销事件
        WSAEventSelect(hSocket, (WSAEVENT) hWriteEvent, 0);
    }

    CloseHandle(hWriteEvent);
    return ((INT) dwSendBytes);
}
Esempio n. 27
0
////////////////////////////////////////////////////////////////////////////////
//	函数名:INT RecvData(
//				SOCKET hSocket,
//				OUT CHAR *pszBuffer,
//				INT nBufferSize,
//				DWORD dwTimeout )
//	用  途:接收数据(阻塞直至收到数据为止)
//	对全局变量的影响:无
//	参  数:
//		hSocket     : 待接收数据的套接字
//		pszBuffer   : 缓冲区
//		nBufferSize : 缓冲区大小
//		dwTimeout   : 接收超时
//	返回值:INT
//		>=0			: 接收到的字节数
//		<0			: 失败(SOCKET_FAIL: -1)
////////////////////////////////////////////////////////////////////////////////
INT CBufSocket::RecvData(SOCKET hSocket, OUT CHAR *pszBuffer, INT nBufferSize, DWORD dwTimeout)
{
    HANDLE hReadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    if (hReadEvent == NULL)
    {
        SetLastError( (INT)GetLastError() );
        return ( SOCKET_FAIL );
    }

    INT		nRecvBytes = 0;
    DWORD	dwWaitResult;
    for (;;)
    {
        // 注册FD_READ | FD_CLOSE 事件
        // (因为可能在等待FD_READ事件中,对方关闭套接字,所以要关注FD_CLOSE)
        if( WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, FD_READ | FD_CLOSE) == SOCKET_ERROR)
        {
            CloseHandle(hReadEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }

        // 等等FD_READ | FD_CLOSE事件的发生
        //dwWaitResult = WSAWaitForMultipleEvents(1, &hReadEvent, TRUE,dwTimeout, TRUE);

        //seawind
        DWORD dwBeginTime = GetTickCount();
        BOOL bDataCome = FALSE;

        while(GetTickCount() - dwBeginTime < dwTimeout)
        {
            //和HttpDownload,FtpDownload类共享一个Event Handle
            if (m_hStopEvent != NULL && (WaitForSingleObject(m_hStopEvent, 0) == WAIT_OBJECT_0))
            {
                //要赶快跳走,用户点了Stop

                CloseHandle(hReadEvent);
                SetLastError( WSAGetLastError() );
                return (SOCKET_FAIL);

                //break;
            }

            dwWaitResult = WSAWaitForMultipleEvents(1, &hReadEvent, TRUE, 0, TRUE);

            if (dwWaitResult == WSA_WAIT_EVENT_0)
            {
                //数据来啦
                bDataCome = TRUE;
                break;
            }

            //空出CPU时间
            Sleep(DEFAULT_BLOCKED_SNDRCV_SLEEP);
        }

        //if (dwWaitResult != WSA_WAIT_EVENT_0)
        if (!bDataCome)
        {
            // 清除事件
            WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);
            CloseHandle(hReadEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }

        //////////////////////////////////////////////////////////////
        ///	注意:即使 dwWaitResult == WSA_WAIT_EVENT0 ,也应该
        ///			进一步检查网络是否发生错误
        ///////////////////////////////////////////////////////////////
        WSANETWORKEVENTS NetEvent;
        if(WSAEnumNetworkEvents(hSocket,(WSAEVENT)hReadEvent,&NetEvent) == SOCKET_ERROR)
        {
            // 清除事件
            WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);
            CloseHandle(hReadEvent);
            SetLastError( WSAGetLastError() );
            return (SOCKET_FAIL);
        }

        //判断发生了什么事件 FD_READ 或 FD_CLOSE
        if( ( NetEvent.lNetworkEvents == FD_CLOSE ) ||
                ( NetEvent.lNetworkEvents	== FD_READ &&
                  NetEvent.iErrorCode[FD_READ_BIT] !=0 ) )	// 发生错误
        {
            // 清除事件
            WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);
            CloseHandle(hReadEvent);
            SetLastError(WSAGetLastError() );
            return (SOCKET_FAIL);
        }
        ////////////////////////////////////////////////////////////////
        // 清除事件
        WSAEventSelect(hSocket, (WSAEVENT) hReadEvent, 0);

        // 接收数据
        if ((nRecvBytes = RecvOnce(hSocket, pszBuffer, nBufferSize)) >= 0)
            break;	// 跳出循环

        INT nErrorCode = -nRecvBytes;

        if ( nErrorCode != WSAEWOULDBLOCK )	//太多的未完成重叠操作
        {
            CloseHandle(hReadEvent);
            SetLastError( nErrorCode );
            return (SOCKET_FAIL);
        }

        //阻塞住了
        ////////////////////////////////////////////////////////////////////////
        //  如果发生阻塞,就等待一定时间后重试,以免CPU轮询浪费时间
        ////////////////////////////////////////////////////////////////////////
        Sleep(DEFAULT_BLOCKED_SNDRCV_SLEEP);
    }

    CloseHandle(hReadEvent);
    return (nRecvBytes);
}
Esempio n. 28
0
DWORD WINAPI CNetworkMgr::AcceptThread( void *pParam )
{
	CNetworkMgr *pNetworkSrv = (CNetworkMgr *)pParam;

	HANDLE	hComPort = pNetworkSrv->m_hCompPort;	//完成端口
	SOCKET	sListen = pNetworkSrv->m_socket;		//监听套接字

	SOCKET	sAccept = INVALID_SOCKET;				//接受客户端连接的套接字
	//sockaddr_in	addrClient;		//客户端SOCKET地址

	while ( pNetworkSrv->m_bRunning )
	{
		DWORD dwRet;
		dwRet = WSAWaitForMultipleEvents( 1, &pNetworkSrv->m_hEvent, FALSE, 100, FALSE );	//等待网络事件

		if ( !pNetworkSrv->m_bRunning )				//服务器停止服务
		{
			break;
		}

		if ( dwRet == WSA_WAIT_TIMEOUT )			//函数调用超时
		{
			continue;
		}

		WSANETWORKEVENTS events;
		int nRet = WSAEnumNetworkEvents( pNetworkSrv->m_socket, pNetworkSrv->m_hEvent, &events );

		if ( SOCKET_ERROR == nRet )
		{
			pNetworkSrv->ShowErrorMsg( "WSAEnumNetworkEvents() failed!\n" );
			break;
		}

		if ( events.lNetworkEvents & FD_ACCEPT )
		{
			if ( events.iErrorCode[FD_ACCEPT_BIT] == 0 && pNetworkSrv->m_bRunning)
			{
				sockaddr_in addrClient;
				int addrClientLen = sizeof( addrClient );
				sAccept = WSAAccept( sListen, (LPSOCKADDR)&addrClient, &addrClientLen, NULL, 0 );
				if ( INVALID_SOCKET == sAccept )
				{
					pNetworkSrv->ShowErrorMsg( "WSAAccept() failed!\n" );
					break;
				}

				CConnect *pConnect = new CConnect( sAccept, addrClient );

				if ( CreateIoCompletionPort( (HANDLE)sAccept, hComPort, (DWORD)pConnect, 0 ) == NULL )
				{
					return -1;
				}

				//加入管理客户端链表
				CConnectMgr *pConnectMgr = CConnectMgr::GetInstance();
				pConnectMgr->AddConnect( pConnect );
				if ( !pConnect->AsyncRecvHead() )
				{
					pConnectMgr->DeleteConnect( pConnect );
				}

			}
		}
		
	}

	//释放资源
	CConnectMgr *pConnectMgr = CConnectMgr::GetInstance();
	pConnectMgr->DeleteAllConnect();
	pConnectMgr->Release();

	//Sleep( 10000 );
	printf( "AcceptThread return\n" );

	return 0;
}
Esempio n. 29
0
unsigned
__stdcall
#endif
nak_routine (
	void*		arg
	)
{
/* dispatch loop */
	pgm_sock_t* nak_sock = (pgm_sock_t*)arg;
#ifndef _WIN32
	int fds;
	fd_set readfds;
#else
	SOCKET recv_sock, repair_sock, pending_sock;
	DWORD cEvents = PGM_SEND_SOCKET_READ_COUNT + 1;
	WSAEVENT waitEvents[ PGM_SEND_SOCKET_READ_COUNT + 1 ];
	DWORD dwTimeout, dwEvents;
	socklen_t socklen = sizeof (SOCKET);

	waitEvents[0] = terminateEvent;
	waitEvents[1] = WSACreateEvent();
	waitEvents[2] = WSACreateEvent();
	waitEvents[3] = WSACreateEvent();
	assert (3 == PGM_SEND_SOCKET_READ_COUNT);
	pgm_getsockopt (nak_sock, IPPROTO_PGM, PGM_RECV_SOCK, &recv_sock, &socklen);
	WSAEventSelect (recv_sock, waitEvents[1], FD_READ);
	pgm_getsockopt (nak_sock, IPPROTO_PGM, PGM_REPAIR_SOCK, &repair_sock, &socklen);
	WSAEventSelect (repair_sock, waitEvents[2], FD_READ);
	pgm_getsockopt (nak_sock, IPPROTO_PGM, PGM_PENDING_SOCK, &pending_sock, &socklen);
	WSAEventSelect (pending_sock, waitEvents[3], FD_READ);
#endif /* !_WIN32 */
	do {
		struct timeval tv;
		char buf[4064];
		pgm_error_t* pgm_err = NULL;
		const int status = pgm_recv (nak_sock, buf, sizeof(buf), 0, NULL, &pgm_err);
		switch (status) {
		case PGM_IO_STATUS_TIMER_PENDING:
			{
				socklen_t optlen = sizeof (tv);
				pgm_getsockopt (sock, IPPROTO_PGM, PGM_TIME_REMAIN, &tv, &optlen);
			}
			goto block;
		case PGM_IO_STATUS_RATE_LIMITED:
			{
				socklen_t optlen = sizeof (tv);
				pgm_getsockopt (sock, IPPROTO_PGM, PGM_RATE_REMAIN, &tv, &optlen);
			}
		case PGM_IO_STATUS_WOULD_BLOCK:
block:
#ifndef _WIN32
			fds = terminate_pipe[0] + 1;
			FD_ZERO(&readfds);
			FD_SET(terminate_pipe[0], &readfds);
			pgm_select_info (nak_sock, &readfds, NULL, &fds);
			fds = select (fds, &readfds, NULL, NULL, PGM_IO_STATUS_WOULD_BLOCK == status ? NULL : &tv);
#else
			dwTimeout = PGM_IO_STATUS_WOULD_BLOCK == status ? WSA_INFINITE : (DWORD)((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
			dwEvents = WSAWaitForMultipleEvents (cEvents, waitEvents, FALSE, dwTimeout, FALSE);
			switch (dwEvents) {
			case WSA_WAIT_EVENT_0+1: WSAResetEvent (waitEvents[1]); break;
			case WSA_WAIT_EVENT_0+2: WSAResetEvent (waitEvents[2]); break;
			case WSA_WAIT_EVENT_0+3: WSAResetEvent (waitEvents[3]); break;
			default: break;
			}
#endif /* !_WIN32 */
			break;

		default:
			if (pgm_err) {
				fprintf (stderr, "%s\n", pgm_err->message ? pgm_err->message : "(null)");
				pgm_error_free (pgm_err);
				pgm_err = NULL;
			}
			if (PGM_IO_STATUS_ERROR == status)
				break;
		}
	} while (!is_terminated);
#ifndef _WIN32
	return NULL;
#else
	WSACloseEvent (waitEvents[1]);
	WSACloseEvent (waitEvents[2]);
	WSACloseEvent (waitEvents[3]);
	_endthread();
	return 0;
#endif
}
Esempio n. 30
0
void main(void)
{
   DWORD EventTotal = 0;
   WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
   LPSOCKET_INFORMATION SocketArray[WSA_MAXIMUM_WAIT_EVENTS];
   CHAR AcceptBuffer[2 * (sizeof(SOCKADDR_IN) + 16)];
   WSAOVERLAPPED ListenOverlapped;
   DWORD Bytes;
   DWORD Index;
   DWORD Flags;
   DWORD BytesTransferred;
   LPSOCKET_INFORMATION SI;
   WSADATA wsaData;
   SOCKET ListenSocket, AcceptSocket;
   SOCKADDR_IN InternetAddr;
   DWORD RecvBytes, SendBytes;
   DWORD i;
   INT Ret;

   if ((Ret = WSAStartup(0x0202,&wsaData)) != 0)
   {
      printf("WSAStartup failed with error %d\n", Ret);
      WSACleanup();
      return;
   }

   if ((ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 
      WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) 
   {
      printf("Failed to get a socket %d\n", WSAGetLastError());
      return;
   }

   InternetAddr.sin_family = AF_INET;
   InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
   InternetAddr.sin_port = htons(PORT);

   if (bind(ListenSocket, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
   {
      printf("bind() failed with error %d\n", WSAGetLastError());
      return;
   }

   if (listen(ListenSocket, 5))
   {
      printf("listen() failed with error %d\n", WSAGetLastError());
      return;
   }

   // Setup the listening socket for connections.

   if ((AcceptSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
      WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) 
   {
      printf("Failed to get a socket %d\n", WSAGetLastError());
      return;
   }

   ZeroMemory(&ListenOverlapped, sizeof(OVERLAPPED));
   if ((EventArray[0] = ListenOverlapped.hEvent = WSACreateEvent()) == WSA_INVALID_EVENT)
   {
      printf("WSACreateEvent failed with error %d\n", WSAGetLastError());
      return;
   }

   EventTotal = 1;

   if (AcceptEx(ListenSocket, AcceptSocket, (PVOID) AcceptBuffer, 0, 
      sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, &Bytes, 
      &ListenOverlapped) == FALSE)
      if (WSAGetLastError() != ERROR_IO_PENDING)
      {
         printf("AcceptEx failed with error %d\n", WSAGetLastError());
         return;
      }

   // Process asynchronous AcceptEx, WSASend, WSARecv requests.

   while(TRUE)
   {

      if ((Index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE,
         WSA_INFINITE, FALSE)) == WSA_WAIT_FAILED)
      {
         printf("WSAWaitForMultipleEvents failed %d\n", WSAGetLastError());
         return;
      } 

      // If the event triggered was zero then a connection attempt was made
      // on our listening socket.
 
      if ((Index - WSA_WAIT_EVENT_0) == 0)
      {
         // Check the returns from the overlapped I/O operation on the listening
         // socket.

         if (WSAGetOverlappedResult(ListenSocket, &(ListenOverlapped), &BytesTransferred,
            FALSE, &Flags) == FALSE)
         {
            printf("WSAGetOverlappedResult failed with error %d\n", WSAGetLastError());
            return;
         }	

         printf("Socket %d connected\n", AcceptSocket);

         if (EventTotal > WSA_MAXIMUM_WAIT_EVENTS)
         {
            printf("Too many connections - closing socket.\n");
            closesocket(AcceptSocket);
            continue;
         } 
         else
         {

            // Create a socket information structure to associate with the accepted socket.

            if ((SocketArray[EventTotal] = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,
               sizeof(SOCKET_INFORMATION))) == NULL)
            {
               printf("GlobalAlloc() failed with error %d\n", GetLastError());
               return;
            } 

            // Fill in the details of our accepted socket.

            SocketArray[EventTotal]->Socket = AcceptSocket;
            ZeroMemory(&(SocketArray[EventTotal]->Overlapped), sizeof(OVERLAPPED));
            SocketArray[EventTotal]->BytesSEND = 0;
            SocketArray[EventTotal]->BytesRECV = 0;
            SocketArray[EventTotal]->DataBuf.len = DATA_BUFSIZE;
            SocketArray[EventTotal]->DataBuf.buf = SocketArray[EventTotal]->Buffer;

            if ((SocketArray[EventTotal]->Overlapped.hEvent = EventArray[EventTotal] = 
				WSACreateEvent()) == WSA_INVALID_EVENT)
            {
               printf("WSACreateEvent() failed with error %d\n", WSAGetLastError());
               return;
            }

            // Post a WSARecv request to to begin receiving data on the socket

            if (WSARecv(SocketArray[EventTotal]->Socket, 
               &(SocketArray[EventTotal]->DataBuf), 1, &RecvBytes, &Flags,
               &(SocketArray[EventTotal]->Overlapped), NULL) == SOCKET_ERROR)
            {
               if (WSAGetLastError() != ERROR_IO_PENDING)
               {
                  printf("WSARecv() failed with error %d\n", WSAGetLastError());
                  return;
               }
            }

            EventTotal++;
         }

         // Make a new socket for accepting future connections and post another
         // AcceptEx call.

         if ((AcceptSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
            WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) 
         {
            printf("Failed to get a socket %d\n", WSAGetLastError());
            return;
         }

         WSAResetEvent(EventArray[0]);

         ZeroMemory(&ListenOverlapped, sizeof(OVERLAPPED));
         ListenOverlapped.hEvent = EventArray[0];

         if (AcceptEx(ListenSocket, AcceptSocket, (PVOID) AcceptBuffer, 0,
            sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, &Bytes, 
            &ListenOverlapped) == FALSE)
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
               printf("AcceptEx failed with error %d\n", WSAGetLastError());
               return;
            }

         continue;
      }

      SI = SocketArray[Index - WSA_WAIT_EVENT_0];
      WSAResetEvent(EventArray[Index - WSA_WAIT_EVENT_0]);

      if (WSAGetOverlappedResult(SI->Socket, &(SI->Overlapped), &BytesTransferred,
         FALSE, &Flags) == FALSE)
      {
         printf("WSAGetOverlappedResult failed with error %d\n", WSAGetLastError());
         return;
      }	
	
      // First check to see if the peer has closed the connection and if so
      // then close the socket and cleanup the SOCKET_INFORMATION structure
      // associated with the socket.

      if (BytesTransferred == 0)
      {
         printf("Closing socket %d\n", SI->Socket);

         if (closesocket(SI->Socket) == SOCKET_ERROR)
         {
            printf("closesocket() failed with error %d\n", WSAGetLastError());
         }

         GlobalFree(SI);
         WSACloseEvent(EventArray[Index - WSA_WAIT_EVENT_0]);

         // Cleanup SocketArray and EventArray by removing the socket event handle
         // and socket information structure if they are not at the end of the
         // arrays.

         if ((Index - WSA_WAIT_EVENT_0) + 1 != EventTotal)
            for (i = Index - WSA_WAIT_EVENT_0; i < EventTotal; i++)
            {
               EventArray[i] = EventArray[i + 1];
               SocketArray[i] = SocketArray[i + 1];
            }

         EventTotal--;

         continue;
      }

      // Check to see if the BytesRECV field equals zero. If this is so, then
      // this means a WSARecv call just completed so update the BytesRECV field
      // with the BytesTransferred value from the completed WSARecv() call.

      if (SI->BytesRECV == 0)
      {
         SI->BytesRECV = BytesTransferred;
         SI->BytesSEND = 0;
      }
      else
      {
         SI->BytesSEND += BytesTransferred;
      }

      if (SI->BytesRECV > SI->BytesSEND)
      {

         // Post another WSASend() request.
         // Since WSASend() is not gauranteed to send all of the bytes requested,
         // continue posting WSASend() calls until all received bytes are sent.

         ZeroMemory(&(SI->Overlapped), sizeof(WSAOVERLAPPED));
         SI->Overlapped.hEvent = EventArray[Index - WSA_WAIT_EVENT_0];

         SI->DataBuf.buf = SI->Buffer + SI->BytesSEND;
         SI->DataBuf.len = SI->BytesRECV - SI->BytesSEND;

         if (WSASend(SI->Socket, &(SI->DataBuf), 1, &SendBytes, 0,
            &(SI->Overlapped), NULL) == SOCKET_ERROR)
         {
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
               printf("WSASend() failed with error %d\n", WSAGetLastError());
               return;
            }
         }
      }
      else
      {
         SI->BytesRECV = 0;

         // Now that there are no more bytes to send post another WSARecv() request.

         Flags = 0;
         ZeroMemory(&(SI->Overlapped), sizeof(WSAOVERLAPPED));
         SI->Overlapped.hEvent = EventArray[Index - WSA_WAIT_EVENT_0];

         SI->DataBuf.len = DATA_BUFSIZE;
         SI->DataBuf.buf = SI->Buffer;

         if (WSARecv(SI->Socket, &(SI->DataBuf), 1, &RecvBytes, &Flags,
            &(SI->Overlapped), NULL) == SOCKET_ERROR)
         {
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
               printf("WSARecv() failed with error %d\n", WSAGetLastError());
               return;
            }
         }
      }
   }
}