void CALLBACK RecvCompletion(DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags) { ClientSession* fromClient = static_cast<OverlappedIO*>(lpOverlapped)->mObject; fromClient->DecRefCount(); if (!fromClient->IsConnected()) return; /// 에러 발생시 해당 세션 종료 if (dwError || cbTransferred == 0) { fromClient->Disconnect(); return; } /// 받은 데이터 처리 fromClient->OnRead(cbTransferred); /// 다시 받기 if (false == fromClient->PostRecv()) { fromClient->Disconnect(); return; } }
/////////////////////////////////////////////////////////// // 비동기 입력 WSARecv()에 의해서, 입력이 완료 되면 콜백으로 RecvCompletion 실행 void CALLBACK RecvCompletion( DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags ) { // lpOverlapped 인자를 OverlappedIO 형태로 형변환 하면 // 해당 구조체의 멤버 변수 mObject => ClientSession* // 바로 이 포인터가 비동기 입력 WSARecv로 보낸 ClientSession 객체의 주소값 // PostRecv 멤소드에서 mOverlappedRecv.mObject = this ; 이 부분 참조 ClientSession* fromClient = static_cast<OverlappedIO*>( lpOverlapped )->m_Object; // Overlapped IO 완료 했음. 카운트 감소 fromClient->DecOverlappedRequest(); if ( !fromClient->IsConnected() ) return; /// 에러 발생시 해당 세션 종료 if ( dwError || cbTransferred == 0 ) { LogD( "[Disconnected from:]ClientSession::RecvCompletion dwError \n" ); fromClient->Disconnect(); return; } /// 받은 데이터 처리 fromClient->OnRead( cbTransferred ); /// 다시 받기 if ( false == fromClient->PostRecv() ) { LogD( "[Disconnected from:]ClientSession::RecvCompletion PostRecv \n" ); fromClient->Disconnect(); return; } }
void ClientManager::CollectGarbageSessions() { std::vector<ClientSession*> disconnectedSessions ; ///FYI: C++ 11 람다를 이용한 스타일 std::for_each(mClientList.begin(), mClientList.end(), [&](ClientList::const_reference it) { ClientSession* client = it.second ; if ( false == client->IsConnected() && 0 == client->GetRefCount() ) disconnectedSessions.push_back(client) ; } ) ; ///FYI: C언어 스타일의 루프 for (size_t i=0 ; i<disconnectedSessions.size() ; ++i) { ClientSession* client = disconnectedSessions[i] ; mClientList.erase(client->mSocket) ; delete client ; } }
void CALLBACK SendCompletion( DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags ) { ClientSession* fromClient = static_cast<OverlappedIO*>(lpOverlapped)->mObject; fromClient->DecOverlappedRequest(); if ( !fromClient->IsConnected() ) return; /// 에러 발생시 해당 세션 종료 if ( dwError || cbTransferred == 0 ) { fromClient->Disconnect(); return; } fromClient->OnWriteComplete(cbTransferred); }
// 비동기 출력 WSASend()에 의해서 출력이 완료 되면 콜백으로 SendCompletion 실행 void CALLBACK SendCompletion( DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags ) { ClientSession* fromClient = static_cast<OverlappedIO*>( lpOverlapped )->m_Object; // Overlapped IO 완료 했음. 카운트 감소 fromClient->DecOverlappedRequest(); if ( !fromClient->IsConnected() ) { return; } /// 에러 발생시 해당 세션 종료 if ( dwError || cbTransferred == 0 ) { LogD( "[Disconnected from:]ClientSession::SendCompletion dwError \n" ); fromClient->Disconnect(); return; } /// 보내기 완료한 데이터를 버퍼에서 제거 fromClient->OnWriteComplete( cbTransferred ); }