// 다수의 워커스레드에서 해당 커넥션(소켓)으로부터 데이타를 받으면 호출됨 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; }
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 } } }
/** * @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 ); }
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()