Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
213 lines
4.5 KiB
C++
213 lines
4.5 KiB
C++
#include "stdafx.h"
|
|
|
|
#include <Stream/Buffer/Buffer.h>
|
|
#include <Stream/Buffer/BufferFactory.h>
|
|
#include <Network/Dispatch/AdminToolDispatch.h>
|
|
|
|
#include <Network/AsyncSock/ClientSock.h>
|
|
#include <Network/SingleSession/ClientSingleSession.h>
|
|
|
|
|
|
CSingleSession::CSingleSession( )
|
|
: m_hSock( INVALID_SOCKET ), m_lpClientAsync( NULL ), m_pPacketDispatch( NULL ), m_bIsConnected( FALSE )
|
|
//m_pRecvBuffer( CREATE_BUFFER( static_cast< unsigned long >( CBufferFactory::GetOptimizedBufferSize( 32768 ) ) ) )
|
|
{
|
|
m_pRecvBuffer = m_DefaultBufferFactory.Create( 32768 );
|
|
}
|
|
|
|
CSingleSession::~CSingleSession( )
|
|
{
|
|
Destroy( );
|
|
|
|
if( m_pRecvBuffer )
|
|
{
|
|
m_DefaultBufferFactory.Release( m_pRecvBuffer );
|
|
//RELEASE_BUFFER( m_pRecvBuffer );
|
|
}
|
|
}
|
|
|
|
bool CSingleSession::Initialize( CPacketToolDispatch* pPacketDispatch )
|
|
{
|
|
if( pPacketDispatch == NULL ) return false;
|
|
|
|
m_lpClientAsync = new CClientSock( this );
|
|
|
|
if( !SetDispatch( pPacketDispatch ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( !m_lpClientAsync->Create( ) )
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CSingleSession::Disconnected( )
|
|
{
|
|
MessageBox( NULL, _T("서버와 연결이 끊어졌습니다."), _T("알림"), MB_OK );
|
|
m_bIsConnected = false;
|
|
}
|
|
|
|
bool CSingleSession::Connect( TCHAR* Address, int nPort )
|
|
{
|
|
if( m_lpClientAsync )
|
|
{
|
|
if( InitializeInternal( m_pPacketDispatch ) )
|
|
{
|
|
if( m_lpClientAsync->Connect(Address, nPort ) )
|
|
{
|
|
m_hSock = m_lpClientAsync->m_hSocket;
|
|
m_bIsConnected = true;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CSingleSession::GetConnected( )
|
|
{
|
|
return m_bIsConnected;
|
|
}
|
|
|
|
bool CSingleSession::InitializeInternal( CPacketToolDispatch* lpPacketDispatch )
|
|
{
|
|
m_bIsConnected = FALSE;
|
|
|
|
CloseSocket( );
|
|
|
|
//m_pRecvBuffer->ClearBuffer( );
|
|
|
|
if( m_pRecvBuffer == NULL )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( m_pPacketDispatch == NULL )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CSingleSession::Send( CBuffer* lpBuffer )
|
|
{
|
|
unsigned long dwSendBytes = 0;
|
|
unsigned long nSendByte = lpBuffer->length( );
|
|
|
|
if( m_hSock != INVALID_SOCKET )
|
|
{
|
|
while( nSendByte )
|
|
{
|
|
dwSendBytes = m_lpClientAsync->Send( lpBuffer->begin( ), lpBuffer->length( ) ); // 전부보낼때까지 버텨~
|
|
|
|
if( dwSendBytes )
|
|
{
|
|
nSendByte -= dwSendBytes;
|
|
}
|
|
else //뭔가 삑싸리
|
|
{
|
|
CloseSocket( );
|
|
//RELEASE_BUFFER( lpBuffer );
|
|
m_DefaultBufferFactory.Release( lpBuffer );
|
|
|
|
AfxMessageBox( _T("패킷보내기 실패 접속 끊어~~"), MB_OK );
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
//RELEASE_BUFFER( lpBuffer );
|
|
m_DefaultBufferFactory.Release( lpBuffer );
|
|
return true;
|
|
}
|
|
|
|
bool CSingleSession::Recv( )
|
|
{
|
|
unsigned long dwReceived = 0; //리쌔에에에에엣~
|
|
unsigned long dwBufferLength = m_pRecvBuffer->remain( ); //현제 버퍼의 남은공간을 가져오자
|
|
|
|
if( m_hSock != INVALID_SOCKET ) // 유효한 소켓?
|
|
{
|
|
dwReceived = m_lpClientAsync->Receive( m_pRecvBuffer->wr_ptr( ), m_pRecvBuffer->remain( ) ); // 전부 받아버려주자~
|
|
|
|
if( dwReceived ) // 뭔가 받았다.
|
|
{
|
|
return Dispatch( dwReceived ); // 패킷 디스패치~ 이
|
|
}
|
|
else // 헉~
|
|
{
|
|
CloseSocket( );
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CSingleSession::Dispatch( unsigned long dwReceivedBytes )
|
|
{
|
|
// 패킷 처리를 하고, 처리하지 못한 양을 앞으로 갖다 붙인다.
|
|
//m_pRecvBuffer->UseBuffer(dwReceivedBytes);
|
|
m_pRecvBuffer->wr_ptr( dwReceivedBytes );
|
|
unsigned long dwDispatchSize = m_pRecvBuffer->length( );
|
|
|
|
// 받은 바이트 수가 0(접속 완료) 이거나, 패킷 처리에 실패하면 Socket을 Close한다.
|
|
bool bResult = ( ( 0 != dwReceivedBytes ) && ( NULL != m_pPacketDispatch ) &&
|
|
m_pPacketDispatch->ParsePacket( m_pRecvBuffer->begin( ), &dwDispatchSize ) );
|
|
|
|
m_pRecvBuffer->rd_ptr( dwDispatchSize ); // 처리한 패킷길이만큼 밀어주고
|
|
m_pRecvBuffer->pop_read_data( ); // 처리한 패킷은 버퍼에서 지워버리고...
|
|
|
|
if( !bResult )
|
|
{
|
|
AfxMessageBox( _T("Dispatch 실패 접속 종료~~"), MB_OK );
|
|
CloseSocket();
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
void CSingleSession::Close( )
|
|
{
|
|
if( m_lpClientAsync ) delete m_lpClientAsync;
|
|
m_hSock = INVALID_SOCKET;
|
|
m_bIsConnected = FALSE;
|
|
}
|
|
|
|
bool CSingleSession::SetDispatch( CPacketToolDispatch* pPacketDispatch )
|
|
{
|
|
if( m_pPacketDispatch ) return false;
|
|
|
|
m_pPacketDispatch = pPacketDispatch;
|
|
m_pPacketDispatch->SetSession(this);
|
|
|
|
return true;
|
|
}
|
|
|
|
void CSingleSession::Destroy( )
|
|
{
|
|
Close( );
|
|
|
|
CloseSocket( );
|
|
|
|
if( m_pPacketDispatch )
|
|
{
|
|
m_pPacketDispatch->Destroy();
|
|
m_pPacketDispatch = NULL;
|
|
}
|
|
|
|
// m_pRecvBuffer->ClearBuffer();
|
|
}
|
|
|
|
void CSingleSession::CloseSocket( )
|
|
{
|
|
if(INVALID_SOCKET != m_hSock)
|
|
{
|
|
shutdown(m_hSock, SD_BOTH);
|
|
closesocket(m_hSock);
|
|
}
|
|
} |