Пример #1
0
// 다수의 워커스레드에서 해당 커넥션(소켓)으로부터 데이타를 받으면 호출됨
bool XEWinConnectionInServer::tRecvData( DWORD readbytes )
{
	bool bOk = true;
	do {
// 		if( IsDisconnected() == TRUE )		// 이런경우가 있음(언젠진 모름)
// 			break;
// 		if( IsDestroy() )
// 			break;
		// 이전에 m_Buffer에 받았던데이타가 아직 큐에 밀어넣지 못한채로 또 불렸다.
		// 받은 데이터를 큐에 밀어넣음.
		int bytePushed = XENetworkConnection::PushBlock( m_Buffer, readbytes );	// 최적화를 위해 만듬. 큐에 하나씩 보내지않고 뭉탱이로 보냄
		const int sizeQ = GetSizeQueue();
		if( sizeQ > GetsizeMaxQ() )
			SetsizeMaxQ( sizeQ );
		// 만약 큐가 꽉차서 더이상 못밀어 넣었다면?
		// 큐는 넉넉하게 잡아놔야겠지만 그것마저 꽉 채울정도라면 비정상으로 보고 끊어야 하지 않을까 싶다.
		// 일단은 로그라도 남겨야 한다.
		// 밀어넣은데이타와 실제 푸쉬된 데이타의 크기가 다르면 에러.
// 		XBREAKF( bytePushed != readbytes, "bytePushed(%d) != readBytes(%d): ip=%s", 
// 														bytePushed, readbytes, m_szIP );
		if( bytePushed != readbytes )	{
			OnError( XENetworkConnection::xERR_Q_IS_FULL, sizeQ );
			DoDisconnect();
			bOk = false;
		}
// 		m_bFlush = TRUE;
	} while(0);
	return bOk;
}
Пример #2
0
void XESocketClientInServer::WorkThread() 
{
//	int sizePacket = 0;
//	int totalRead = 0;
	while(1) {
		// 큐에 받을 버퍼가 더이상 없으면 다 퍼갈때까지 걍 대기
// 		if( XBREAK( XENetworkConnection::IsqBufferFull() == TRUE ) )
// 			continue;
		// 소켓에서 패킷을 읽어 버퍼에 저장
		int readbytes = recv( m_Socket, (char *)m_Buffer, sizeof(m_Buffer), 0 );		// 버퍼크기만큼 패킷을 읽어온다
		{
			XAUTO_LOCK;
			if( readbytes <= 0 ) {
				// 접속이 끊어짐
				Set_bConnected( FALSE );
				XTRACE("외부요인에 의해 연결 끊김.");
//				ClearConnection();		// 패킷 버퍼 마저다 처리하려고 큐는 클리어 안함.
				return;
			}
			XBREAK( readbytes > ( int )sizeof( m_Buffer ) );
			// 버퍼의 내용을 큐로 보냄
			XENetworkConnection::PushBlock( m_Buffer, readbytes );		// 받은 데이터를 큐에 보냄
#if _DEV_LEVEL <= DLV_OPEN_BETA
			const int sizeQ = GetSizeQueue();
			if( sizeQ > GetsizeMaxQ() )
				SetsizeMaxQ( sizeQ );
#endif
		}
	}
}
Пример #3
0
/**
 * @function BuildManifold
 */
void HP2D::BuildManifold( Vertice _v0 ) {

    Vertice* va;
    Vertice vt;
	Vertice* vb;
    std::vector<Vertice> S; 
    std::vector<Vertice*> B; 

	InsertQueue( _v0 );

    do{
    	va = PopQueue();        
        S = Successors( va );
        
        for( int i = 0; i < S.size(); i++ ) {
            vt = S[i];
            InsertVertice( vt );
            InsertEdge( &vt, va );
            if( vt.GetDist() < mDIST_MAX ) {
                InsertQueue( vt );
            }
            B = GetAdjacent( va->Adjacent() );
            
            for( unsigned j = 0; j < B.size(); j++ ) {
                vb = B[j];
                if( InSet( vb->GetPos(), vt.Neighbors() ) ) {
                    InsertEdge( &vt, vb );
                }          
            }
        } 
    } while( GetSizeQueue() > 0 ); 
}
Пример #4
0
void XEWinSocketSvr::WorkThread()
{
	unsigned long readbytes;
	unsigned long dwCompKey;
//	OVERLAPPED * pOverlap;
	XE::xOVERLAPPED* pOverlap = nullptr;
	while( 1 ) {
		// 클라이언트로부터 데이타가 오길 기다림
		BOOL bRet = GetQueuedCompletionStatus( m_hIOCP, &readbytes, &dwCompKey, (LPOVERLAPPED*)&pOverlap, INFINITE );
		// TODO:
#pragma message("리턴값처리 제대로 할것. ")
		if( bRet == FALSE ) {
			auto err = GetLastError();
			TCHAR* szMsg = nullptr;
			FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER
									, nullptr
									, err
									, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT)
									, (TCHAR*)&szMsg
									, 0
									, nullptr );
			if( pOverlap == nullptr )	{
				return;
			} else {
				if( readbytes ) {
					// 패킷을 dequeue했지만 실패한I/O에 대한 dequeue였다.
				} else {
					// 클라이언트 소켓 close
				}
			}
		} else {
			if( pOverlap == nullptr )
				return;
		}
		const auto typeEvent = pOverlap->typeEvent;
		if( bRet == FALSE && pOverlap == nullptr ) {
			return;
		}
		// 어떤 커넥션으로부터 데이타가 도착함.
		// 어떤 클라이언트 연결로부터 왔는지 알아냄
		ID idConnect = (ID)dwCompKey;
		// 해당 커넥션객체를 찾음.
		auto spConnect = FindspConnect( idConnect );	// 스레드안전
		//
		if( spConnect ) {
			XAUTO_LOCK3( spConnect );
			//
			if( readbytes != 0 ) {
#if _DEV_LEVEL <= DLV_DEV_EXTERNAL
				if( spConnect->IsDisconnected() ) {
					CONSOLE( "connect", "끊어진 소켓에서 IOCP발생" );
				}
#endif
				// 받은 데이터를 큐에 밀어넣음
				// 접속되고 곧바로 recv가 온다면 커넥션객체에 채 XUser가 붙기도 전에 이게 호출될수도 있음.
				// 그러므로 그런패킷은 일단 커넥션 큐안에 쌓아둬야 한다.
				if( !spConnect->IsDisconnected() && !spConnect->IsbDestroy() ) {
					if( typeEvent == 1 ) {		// send의 완료는 따로 처리할것이 없음.
						// send
						continue;
// 						spConnect->SendData( )
					}
					else {
						// recv
						spConnect->tRecvData( readbytes );
#if _DEV_LEVEL <= DLV_OPEN_BETA
						const int sizeQ = spConnect->GetSizeQueue();
						// 최대 큐크기 표시용
						if( sizeQ > m_sizeMaxQ )
							m_sizeMaxQ = sizeQ;
#endif
						// 비동기 recv를 큐에 올림
						spConnect->tWSARecv();
					}
				}
			} else 	{
				// 접속 끊김
				// 서버의 다른데서 소켓닫으면 여기로 들어오나?
				spConnect->Set_bConnected( FALSE );		// 연결해제 플래그만 켜고 실제 삭제처리는 메인스레드에서.
				if( bRet && pOverlap == nullptr ) {
					spConnect->DoDisconnect();
					return;
				}
				BTRACE( "disconnected:%s", GetszName() );
				continue;		// 끊긴 커넥션이므로 더이상 처리안해도 된다.
			} // if( readbytes == 0 )	{	// 접속 끊김
		} else {
#if (_DEV_LEVEL <= DLV_DEV_EXTERNAL) && !defined(_XBOT)
			CONSOLE( "이미 삭제되거나 없는 연결에서 데이타가 도착했습니다." );
#endif
		} // if( pConn ) {
		Sleep( m_msecSleepRecv );
	} // while(1)
} // WorkThread()