LosaDev source snapshot 2019

This commit is contained in:
LosaDev committed 2026-11-07 13:30:45 +07:00
commit c198676e97
20588 files changed
+8812878

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
#include "stdafx.h"
#include "cPacket.h"
#include "cIocpContext.h"
#include "cConnectorQueue.h"
#include "cSystem.h"
#include "../include/cSingleton.h"
#include "../include/IIocpContext.h"
#include "../include/INetwork.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
INetwork::INetwork(void)
{
}
INetwork::~INetwork(void)
{
}
//
//////////////////////////////////////////////////////////////////////
// Operation
//////////////////////////////////////////////////////////////////////
BOOL INetwork::Flush(IIocpContext *context)
{
cIocpContext* iocpContext = static_cast<cIocpContext*>(context);
return iocpContext->Flush();
}
BOOL INetwork::Send( IIocpContext *context,
const uint16 command,
const uint8* buffer,
const uint16 length,
const BOOL encoding)
{
cIocpContext* iocpContext = static_cast<cIocpContext*>(context);
static cPacket *packet = NULL;
if(NULL == packet)
{
packet = new cPacket(cSingleton<cSystem>::GetInstance()->GetEncoding());
}
packet->Make( command,
buffer,
length,
encoding ? 1 : 0 );
return iocpContext->SendRequest(packet->GetBuffer(), packet->GetLength());
}
void INetwork::Send( const uint32 ID,
const uint16 command,
const uint8* buffer,
const uint16 length)
{
cConnectorQueue* connectorQueue = cSingleton<cSystem>::GetInstance()->GetConnectorQueue();
if(connectorQueue)
{
connectorQueue->PushCommand( ID,
command,
buffer,
length);
}
}
+105
View File
@@ -0,0 +1,105 @@
#include "stdafx.h"
#include "cSystem.h"
#include "../include/ISystem.h"
#include "../include/IProcessor.h"
#include "../include/cSingleton.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ISystem::ISystem(void)
{
Init();
}
ISystem::~ISystem(void)
{
Destroy();
}
void ISystem::Init()
{
}
void ISystem::Destroy()
{
Stop();
Cleanup();
}
//////////////////////////////////////////////////////////////////////
// Operation
//////////////////////////////////////////////////////////////////////
BOOL ISystem::Startup(const uint32 maxSession, const uint32 maxPacket, const uint32 maxQueue, const uint32 encoding) const
{
cSystem* system = cSingleton<cSystem>::GetInstance();
return system->Startup(maxSession, maxPacket, maxQueue, encoding);
}
void ISystem::Cleanup() const
{
cSystem* system = cSingleton<cSystem>::GetInstance();
system->Cleanup();
}
BOOL ISystem::Start(const int32 workerCount, const int32 commandCount, const int32 connectorCount) const
{
cSystem* system = cSingleton<cSystem>::GetInstance();
if(!system->StartModule(E_THREADID_WORKER, workerCount)) return FALSE;
if(!system->StartModule(E_THREADID_COMMAND, commandCount)) return FALSE;
if(!system->StartModule(E_THREADID_CONNECTOR, connectorCount)) return FALSE;
return TRUE;
}
void ISystem::Stop() const
{
cSystem* system = cSingleton<cSystem>::GetInstance();
system->EndModule();
}
void ISystem::SetProcessor(IProcessor* processor) const
{
cSystem* system = cSingleton<cSystem>::GetInstance();
system->SetProcessor(processor);
}
void ISystem::SetEvent(const uint32 connectId, const uint32 disconnectId) const
{
cSystem* system = cSingleton<cSystem>::GetInstance();
system->SetEvent(connectId, disconnectId);
}
BOOL ISystem::Listen(const uint16 port, const uint32 backlog) const
{
cSystem* system = cSingleton<cSystem>::GetInstance();
return system->Listen(port, backlog);
}
BOOL ISystem::Connect(const uint32 serverId, const TCHAR* IP, const uint16 port) const
{
cSystem* system = cSingleton<cSystem>::GetInstance();
return system->Connect(serverId, IP, port);
}
//////////////////////////////////////////////////////////////////////
// Operation::queue
//////////////////////////////////////////////////////////////////////
BOOL ISystem::Call(const uint32 command, const uint8* buffer, const uint32 length) const
{
cCommandQueue* pCommandQueue = cSingleton<cSystem>::GetInstance()->GetCommandQueue();
if(pCommandQueue)
{
pCommandQueue->PushCommand(
static_cast<uint32>(0),
command,
buffer,
length);
return TRUE;
}
return FALSE;
}
@@ -0,0 +1,290 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{B21F9429-8D8E-491B-A110-85406E3EA30E}</ProjectGuid>
<RootNamespace>LS_network</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\lib\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">networkD</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">network</TargetName>
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include;$(IncludePath)</IncludePath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0412</Culture>
</ResourceCompile>
<Lib>
<OutputFile>..\lib\network.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)$(TargetName).bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
<BrowseInformation>
</BrowseInformation>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0412</Culture>
</ResourceCompile>
<Lib>
<OutputFile>..\lib\networkD.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>$(OutDir)$(TargetName).bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cDoubleOV.cpp" />
<ClCompile Include="cSystem.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cModule.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cBaseThread.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cCommandThread.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cConnectorThread.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cWorkerThread.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cCommunicator.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cBaseQueueElem.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cCommandQueue.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cCommandQueueElem.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cConnectorQueue.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cConnectorQueueElem.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cIocpQueue.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cIOCP.cpp" />
<ClCompile Include="cIocpContext.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cSocket.cpp" />
<ClCompile Include="cStorage.cpp" />
<ClCompile Include="cIocpOv.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cNetwork.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cClientSocket.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cServerSocket.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cServerSocketManager.cpp" />
<ClCompile Include="cEncrypt.cpp" />
<ClCompile Include="cPacket.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cConnector.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cConnectorManager.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="cPooler.cpp" />
<ClCompile Include="StdAfx.cpp" />
<ClCompile Include="INetwork.cpp" />
<ClCompile Include="ISystem.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="cDoubleOV.h" />
<ClInclude Include="cSystem.h" />
<ClInclude Include="cModule.h" />
<ClInclude Include="cBaseThread.h" />
<ClInclude Include="cCommandThread.h" />
<ClInclude Include="cConnectorThread.h" />
<ClInclude Include="cWorkerThread.h" />
<ClInclude Include="cCommunicator.h" />
<ClInclude Include="cBaseQueueElem.h" />
<ClInclude Include="cCommandQueue.h" />
<ClInclude Include="cCommandQueueElem.h" />
<ClInclude Include="cConnectorQueue.h" />
<ClInclude Include="cConnectorQueueElem.h" />
<ClInclude Include="cIocpQueue.h" />
<ClInclude Include="cIOCP.h" />
<ClInclude Include="cIocpContext.h" />
<ClInclude Include="cSocket.h" />
<ClInclude Include="cStorage.h" />
<ClInclude Include="cIocpOv.h" />
<ClInclude Include="cOverlapped.h" />
<ClInclude Include="cNetwork.h" />
<ClInclude Include="cClientSocket.h" />
<ClInclude Include="cServerSocket.h" />
<ClInclude Include="cServerSocketManager.h" />
<ClInclude Include="cEncrypt.h" />
<ClInclude Include="cHeader.h" />
<ClInclude Include="cPacket.h" />
<ClInclude Include="cConnector.h" />
<ClInclude Include="cConnectorManager.h" />
<ClInclude Include="cPooler.h" />
<ClInclude Include="StdAfx.h" />
<ClInclude Include="include\IIocpContext.h" />
<ClInclude Include="include\INetwork.h" />
<ClInclude Include="include\IProcessor.h" />
<ClInclude Include="include\ISystem.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,252 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="System">
<UniqueIdentifier>{e16f246a-8897-4536-b351-e5084e5ef742}</UniqueIdentifier>
</Filter>
<Filter Include="System\Module">
<UniqueIdentifier>{a3e95b38-4f39-4e87-9ef8-8cd3c7e3ccce}</UniqueIdentifier>
</Filter>
<Filter Include="System\Module\Thread">
<UniqueIdentifier>{b266f50d-ef3d-41b3-80dd-8616cd8d781f}</UniqueIdentifier>
</Filter>
<Filter Include="System\Communicator">
<UniqueIdentifier>{51010f03-92bf-4efa-be8c-efc35e14380c}</UniqueIdentifier>
</Filter>
<Filter Include="System\Communicator\Queue">
<UniqueIdentifier>{7125662f-5734-45fc-9555-784d9e34450d}</UniqueIdentifier>
</Filter>
<Filter Include="System\IOCP">
<UniqueIdentifier>{dc9fa1a9-faec-419a-9780-bc517d57f4fb}</UniqueIdentifier>
</Filter>
<Filter Include="System\IOCP\Context">
<UniqueIdentifier>{23dfd981-7754-4223-a95a-2ed5a5f81d7c}</UniqueIdentifier>
</Filter>
<Filter Include="System\IOCP\Overlapped">
<UniqueIdentifier>{eb89b0cb-f88e-4431-9871-77074455a144}</UniqueIdentifier>
</Filter>
<Filter Include="System\Network">
<UniqueIdentifier>{0c69a32c-7e1a-4bfe-92f4-bbce0d4cc01d}</UniqueIdentifier>
</Filter>
<Filter Include="System\Network\Socket">
<UniqueIdentifier>{2e65f9bf-8a24-4697-9296-545a16172882}</UniqueIdentifier>
</Filter>
<Filter Include="System\Network\Packet">
<UniqueIdentifier>{5a4650d8-a865-4bbb-ae97-738eba1d2364}</UniqueIdentifier>
</Filter>
<Filter Include="System\Network\Connector">
<UniqueIdentifier>{225721ee-f19b-4950-97f1-03e6266bea72}</UniqueIdentifier>
</Filter>
<Filter Include="System\Network\Pooler">
<UniqueIdentifier>{3a989e02-caae-4eb2-ad5e-8ae50220b92e}</UniqueIdentifier>
</Filter>
<Filter Include="Etc">
<UniqueIdentifier>{70ba6b9f-0eeb-4e30-9d01-1faa067695c4}</UniqueIdentifier>
</Filter>
<Filter Include="Etc\Interface">
<UniqueIdentifier>{1d5bd7ac-fd3c-4cc2-b9ae-5a080822d0c6}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cSystem.cpp">
<Filter>System</Filter>
</ClCompile>
<ClCompile Include="cModule.cpp">
<Filter>System\Module</Filter>
</ClCompile>
<ClCompile Include="cBaseThread.cpp">
<Filter>System\Module\Thread</Filter>
</ClCompile>
<ClCompile Include="cCommandThread.cpp">
<Filter>System\Module\Thread</Filter>
</ClCompile>
<ClCompile Include="cConnectorThread.cpp">
<Filter>System\Module\Thread</Filter>
</ClCompile>
<ClCompile Include="cWorkerThread.cpp">
<Filter>System\Module\Thread</Filter>
</ClCompile>
<ClCompile Include="cCommunicator.cpp">
<Filter>System\Communicator</Filter>
</ClCompile>
<ClCompile Include="cBaseQueueElem.cpp">
<Filter>System\Communicator\Queue</Filter>
</ClCompile>
<ClCompile Include="cCommandQueue.cpp">
<Filter>System\Communicator\Queue</Filter>
</ClCompile>
<ClCompile Include="cCommandQueueElem.cpp">
<Filter>System\Communicator\Queue</Filter>
</ClCompile>
<ClCompile Include="cConnectorQueue.cpp">
<Filter>System\Communicator\Queue</Filter>
</ClCompile>
<ClCompile Include="cConnectorQueueElem.cpp">
<Filter>System\Communicator\Queue</Filter>
</ClCompile>
<ClCompile Include="cIocpQueue.cpp">
<Filter>System\Communicator\Queue</Filter>
</ClCompile>
<ClCompile Include="cIOCP.cpp">
<Filter>System\IOCP</Filter>
</ClCompile>
<ClCompile Include="cIocpContext.cpp">
<Filter>System\IOCP\Context</Filter>
</ClCompile>
<ClCompile Include="cSocket.cpp">
<Filter>System\IOCP\Context</Filter>
</ClCompile>
<ClCompile Include="cStorage.cpp">
<Filter>System\IOCP\Context</Filter>
</ClCompile>
<ClCompile Include="cIocpOv.cpp">
<Filter>System\IOCP\Overlapped</Filter>
</ClCompile>
<ClCompile Include="cNetwork.cpp">
<Filter>System\Network</Filter>
</ClCompile>
<ClCompile Include="cClientSocket.cpp">
<Filter>System\Network\Socket</Filter>
</ClCompile>
<ClCompile Include="cServerSocket.cpp">
<Filter>System\Network\Socket</Filter>
</ClCompile>
<ClCompile Include="cServerSocketManager.cpp">
<Filter>System\Network\Socket</Filter>
</ClCompile>
<ClCompile Include="cEncrypt.cpp">
<Filter>System\Network\Packet</Filter>
</ClCompile>
<ClCompile Include="cPacket.cpp">
<Filter>System\Network\Packet</Filter>
</ClCompile>
<ClCompile Include="cConnector.cpp">
<Filter>System\Network\Connector</Filter>
</ClCompile>
<ClCompile Include="cConnectorManager.cpp">
<Filter>System\Network\Connector</Filter>
</ClCompile>
<ClCompile Include="cPooler.cpp">
<Filter>System\Network\Pooler</Filter>
</ClCompile>
<ClCompile Include="StdAfx.cpp">
<Filter>Etc</Filter>
</ClCompile>
<ClCompile Include="INetwork.cpp">
<Filter>Etc\Interface</Filter>
</ClCompile>
<ClCompile Include="ISystem.cpp">
<Filter>Etc\Interface</Filter>
</ClCompile>
<ClCompile Include="cDoubleOV.cpp">
<Filter>System\IOCP\Overlapped</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="cSystem.h">
<Filter>System</Filter>
</ClInclude>
<ClInclude Include="cModule.h">
<Filter>System\Module</Filter>
</ClInclude>
<ClInclude Include="cBaseThread.h">
<Filter>System\Module\Thread</Filter>
</ClInclude>
<ClInclude Include="cCommandThread.h">
<Filter>System\Module\Thread</Filter>
</ClInclude>
<ClInclude Include="cConnectorThread.h">
<Filter>System\Module\Thread</Filter>
</ClInclude>
<ClInclude Include="cWorkerThread.h">
<Filter>System\Module\Thread</Filter>
</ClInclude>
<ClInclude Include="cCommunicator.h">
<Filter>System\Communicator</Filter>
</ClInclude>
<ClInclude Include="cBaseQueueElem.h">
<Filter>System\Communicator\Queue</Filter>
</ClInclude>
<ClInclude Include="cCommandQueue.h">
<Filter>System\Communicator\Queue</Filter>
</ClInclude>
<ClInclude Include="cCommandQueueElem.h">
<Filter>System\Communicator\Queue</Filter>
</ClInclude>
<ClInclude Include="cConnectorQueue.h">
<Filter>System\Communicator\Queue</Filter>
</ClInclude>
<ClInclude Include="cConnectorQueueElem.h">
<Filter>System\Communicator\Queue</Filter>
</ClInclude>
<ClInclude Include="cIocpQueue.h">
<Filter>System\Communicator\Queue</Filter>
</ClInclude>
<ClInclude Include="cIOCP.h">
<Filter>System\IOCP</Filter>
</ClInclude>
<ClInclude Include="cIocpContext.h">
<Filter>System\IOCP\Context</Filter>
</ClInclude>
<ClInclude Include="cSocket.h">
<Filter>System\IOCP\Context</Filter>
</ClInclude>
<ClInclude Include="cStorage.h">
<Filter>System\IOCP\Context</Filter>
</ClInclude>
<ClInclude Include="cIocpOv.h">
<Filter>System\IOCP\Overlapped</Filter>
</ClInclude>
<ClInclude Include="cOverlapped.h">
<Filter>System\IOCP\Overlapped</Filter>
</ClInclude>
<ClInclude Include="cNetwork.h">
<Filter>System\Network</Filter>
</ClInclude>
<ClInclude Include="cClientSocket.h">
<Filter>System\Network\Socket</Filter>
</ClInclude>
<ClInclude Include="cServerSocket.h">
<Filter>System\Network\Socket</Filter>
</ClInclude>
<ClInclude Include="cServerSocketManager.h">
<Filter>System\Network\Socket</Filter>
</ClInclude>
<ClInclude Include="cEncrypt.h">
<Filter>System\Network\Packet</Filter>
</ClInclude>
<ClInclude Include="cHeader.h">
<Filter>System\Network\Packet</Filter>
</ClInclude>
<ClInclude Include="cPacket.h">
<Filter>System\Network\Packet</Filter>
</ClInclude>
<ClInclude Include="cConnector.h">
<Filter>System\Network\Connector</Filter>
</ClInclude>
<ClInclude Include="cConnectorManager.h">
<Filter>System\Network\Connector</Filter>
</ClInclude>
<ClInclude Include="cPooler.h">
<Filter>System\Network\Pooler</Filter>
</ClInclude>
<ClInclude Include="StdAfx.h">
<Filter>Etc</Filter>
</ClInclude>
<ClInclude Include="include\IIocpContext.h">
<Filter>Etc\Interface</Filter>
</ClInclude>
<ClInclude Include="include\INetwork.h">
<Filter>Etc\Interface</Filter>
</ClInclude>
<ClInclude Include="include\IProcessor.h">
<Filter>Etc\Interface</Filter>
</ClInclude>
<ClInclude Include="include\ISystem.h">
<Filter>Etc\Interface</Filter>
</ClInclude>
<ClInclude Include="cDoubleOV.h">
<Filter>System\IOCP\Overlapped</Filter>
</ClInclude>
</ItemGroup>
</Project>
+1
View File
@@ -0,0 +1 @@
#include "StdAfx.h"
+27
View File
@@ -0,0 +1,27 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__F77826AC_E455_4A39_87C3_D426BEC2023F__INCLUDED_)
#define AFX_STDAFX_H__F77826AC_E455_4A39_87C3_D426BEC2023F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../include/Common.h"
#include <winsock2.h>
#include <windows.h>
#include <mswsock.h>
#include <tchar.h>
extern void Trace( const TCHAR *lpszFormat, ... );
extern void Debug( const TCHAR *lpszFormat, ... );
extern void Information( const TCHAR *lpszFormat, ... );
extern void Debug();
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__F77826AC_E455_4A39_87C3_D426BEC2023F__INCLUDED_)
+11
View File
@@ -0,0 +1,11 @@
#pragma once
typedef enum E_THREADID
{
E_THREADID_WORKER = 1,
E_THREADID_COMMAND,
E_THREADID_CONNECTOR
};
@@ -0,0 +1,85 @@
// cAcceptThread.cpp: implementation of the cAcceptThread class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cIocpContext.h"
#include "cAcceptThread.h"
#include "cSystem.h"
#include "cSingleton.h"
void Trace( char *lpszFormat, ... );
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cAcceptThread::cAcceptThread()
{
Init();
}
cAcceptThread::~cAcceptThread()
{
Destroy();
}
void cAcceptThread::Init()
{
}
void cAcceptThread::Destroy()
{
}
void cAcceptThread::Process()
{
/*
SOCKADDR sa;
cIocpContext* pIocpContext = NULL;
cSystem* pSystem = cSingleton<cSystem>::GetInstance();
cServerSocket* pServerSocket = pSystem->GetServerSocket();
cIocpOperation* pIocpOperation = pSystem->GetIocpOperation();
cIocpContextPool* pIocpContextPool = pSystem->GetIocpContextPool();
Trace( "AcceptThread :: %lu\n", GetCurrentThreadId() );
while( !IsTerminated() )
{
// wait for a client
SOCKET hSocket = pServerSocket->AcceptRequest( sa );
if( hSocket == INVALID_SOCKET ) continue;
// pop a context from queue
pIocpContext = pIocpContextPool->Pop();
if( !pIocpContext ) continue;
// reset all data
pIocpContext->Reset();
// sets a socket handle and option
pIocpContext->SetSocketHandle( hSocket );
pIocpContext->SetSocketOption();
// associcate a socket
if( pIocpOperation->AssocInstance( (HANDLE)hSocket, pIocpContext ) )
{
if( pIocpContext->ReceiveRequest() )
{
// associated successfully and issue a receive
Trace( "connected, entity = %lu\n", pIocpContext->GetEntity() );
continue;
}
}
pIocpContext->Sleep();
pIocpContextPool->Push( pIocpContext );
}
*/
}
@@ -0,0 +1,31 @@
// cAcceptThread.h: interface for the cAcceptThread class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CACCEPTTHREAD_H__91DFC159_6F46_446D_BF50_61F70967AB34__INCLUDED_)
#define AFX_CACCEPTTHREAD_H__91DFC159_6F46_446D_BF50_61F70967AB34__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "cBaseThread.h"
class cAcceptThread : public cBaseThread
{
public:
cAcceptThread();
virtual ~cAcceptThread();
void Init();
void Destroy();
protected:
virtual void Process();
};
#endif // !defined(AFX_CACCEPTTHREAD_H__91DFC159_6F46_446D_BF50_61F70967AB34__INCLUDED_)
@@ -0,0 +1,45 @@
// cBaseQueueElem.cpp: implementation of the cBaseQueueElem class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "cSystem.h"
#include "cBaseQueueElem.h"
#include "../include/cSingleton.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cBaseQueueElem::cBaseQueueElem()
{
Init();
}
cBaseQueueElem::~cBaseQueueElem()
{
Destroy();
}
void cBaseQueueElem::Init()
{
m_buffer.Create(cSingleton<cSystem>::GetInstance()->GetPacket());
}
void cBaseQueueElem::Destroy()
{
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
BOOL cBaseQueueElem::CopyData(const uint8* buffer, const uint32 length)
{
if(!m_buffer.Copy(buffer, length))
{
m_buffer.Create(length);
m_buffer.Copy(buffer, length);
}
return TRUE;
}
@@ -0,0 +1,22 @@
#pragma once
#include "cBuffer.h"
class cBaseQueueElem
{
public:
cBaseQueueElem();
virtual ~cBaseQueueElem();
void Init();
void Destroy();
public:
BOOL CopyData(const uint8* buffer, const uint32 length);
const uint32 GetLength() { return m_buffer.GetLength(); }
const uint8* GetData() { return m_buffer.GetBuffer(); }
protected:
cBuffer m_buffer;
};
@@ -0,0 +1,91 @@
// cBaseThread.cpp: implementation of the cBaseThread class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cBaseThread.h"
#include <process.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cBaseThread::cBaseThread()
{
Init();
}
cBaseThread::~cBaseThread()
{
Destroy();
}
void cBaseThread::Init()
{
m_threadId = 0;
m_thread = 0;
m_terminated = FALSE;
}
void cBaseThread::Destroy()
{
// if still alive, terminate thread
if( !IsTerminated() )
{
Terminate();
}
// close thread handle
if( m_thread )
{
CloseHandle( m_thread );
m_thread = NULL;
}
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
// Thread시작
BOOL cBaseThread::StartThread()
{
if( IsRunning() ) return FALSE;
m_thread = reinterpret_cast<HANDLE>(_beginthreadex( NULL,
0,
&ThreadProc,
this,
0,
reinterpret_cast<uint*>(&m_threadId) ) );
if( m_thread == 0 )
{
m_threadId = 0;
return FALSE;
}
return TRUE;
}
unsigned __stdcall cBaseThread::ThreadProc( void* handle )
{
unsigned retCode = 0;
cBaseThread* thread = static_cast<cBaseThread*>(handle);
while( !thread->IsRunning() )
{
// 스레드 핸들을 제대로 넘겨받지 못했을 경우 기다린다.
Sleep( 1 );
}
// thread loop
thread->Process();
_endthreadex( retCode );
return retCode;
}
+34
View File
@@ -0,0 +1,34 @@
#pragma once
//////////////////////////////////////////////////////////////////////
// Thread 기본 클래스, 쓰레드 생성 및 가상함수 호출
//////////////////////////////////////////////////////////////////////
class cBaseThread
{
public:
cBaseThread();
virtual ~cBaseThread();
void Init();
void Destroy();
public:
BOOL IsRunning() { return m_thread ? TRUE : FALSE; }
BOOL IsTerminated() { return m_terminated; }
uint32 GetThreadID() { return m_threadId; }
void Terminate() { m_terminated = TRUE; }
BOOL StartThread(); // Thread 시작
protected:
virtual void Process() = 0;
static unsigned __stdcall ThreadProc( void* handle );
protected:
uint32 m_threadId;
HANDLE m_thread;
BOOL m_terminated;
};
+55
View File
@@ -0,0 +1,55 @@
// cBuffer.h: interface for the cBuffer class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CBUFFER_H__ECE7A49E_767B_4F38_91CE_A4795B0F4535__INCLUDED_)
#define AFX_CBUFFER_H__ECE7A49E_767B_4F38_91CE_A4795B0F4535__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class cBuffer
{
public:
cBuffer();
cBuffer( uint32 uBuffLen );
virtual ~cBuffer();
void Init();
void Destroy();
public:
bool Create( uint32 uBuffLen );
bool Erase();
public:
void SetLength( uint32 unLen ) { m_unLen = unLen; }
uint32 GetMaxLength() { return m_unMax; }
uint32 GetLength() { return m_unLen; }
uint8* GetBuffer() const { return m_pDT; }
char* GetString() const { return reinterpret_cast<char*>(m_pDT); }
uint8* GetBuffer( uint32 unLen ) const { return (m_pDT+unLen); }
bool Copy( const char* pDT );
bool Copy( uint32 unDst, const char* pDT );
bool Copy( const uint8* pDT, uint32 unLen );
bool Copy( uint32 unDst, const uint8* pDT, uint32 unLen );
bool Append( const char pDT );
bool Append( const char* pDT );
bool Append( const uint8* pDT, uint32 unLen );
protected:
uint8* m_pDT;
uint32 m_unLen;
uint32 m_unMax;
};
#endif // !defined(AFX_CBUFFER_H__ECE7A49E_767B_4F38_91CE_A4795B0F4535__INCLUDED_)
@@ -0,0 +1,243 @@
// cClientSocket.cpp: implementation of the cClientSocket class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cSystem.h"
#include "cClientSocket.h"
#include "../include/cSingleton.h"
#include <process.h>
extern DWORD _tinet_addr(const TCHAR *IP);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cClientSocket::cClientSocket()
{
Init();
}
cClientSocket::~cClientSocket()
{
Destroy();
}
void cClientSocket::Init()
{
m_socket = INVALID_SOCKET;
ZeroMemory( &m_sockAddr, sizeof(SOCKADDR_IN) );
}
void cClientSocket::Destroy()
{
CloseSocket();
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
BOOL cClientSocket::Startup()
{
WSADATA wsaData;
ZeroMemory( &wsaData, sizeof(WSADATA) );
if( WSAStartup(MAKEWORD( 2, 2 ), &wsaData) != 0 )
{
Trace( _T("cClientSocket::Startup() Failed\n") );
return FALSE;
}
return TRUE;
}
void cClientSocket::Cleanup()
{
WSACleanup();
}
BOOL cClientSocket::Create()
{
if(INVALID_SOCKET != m_socket)
return TRUE;
m_socket = WSASocket( AF_INET,
SOCK_STREAM,
IPPROTO_TCP,
NULL,
NULL,
WSA_FLAG_OVERLAPPED );
if( m_socket != INVALID_SOCKET )
{
return SetSocketOption();
}
return FALSE;
}
BOOL cClientSocket::Connect( const TCHAR *IP, const uint16 port )
{
if( IP ) // IP와 포트가 입력됐을 경우 새로운 주소로 접속을 시도한다
{
m_sockAddr.sin_family = AF_INET;
m_sockAddr.sin_addr.s_addr = _tinet_addr(IP);
m_sockAddr.sin_port = htons(port);
}
else
{
int32 nResult = connect(m_socket,
(LPSOCKADDR)&m_sockAddr,
sizeof(SOCKADDR_IN) );
if( (nResult != SOCKET_ERROR) || (WSAGetLastError() == WSAEWOULDBLOCK) )
{
OnConnected();
return TRUE;
}
return FALSE;
}
return TRUE;
}
BOOL cClientSocket::Reconnect()
{
CloseSocket();
OnDisconnected();
while(!Create())
{
CloseSocket();
Sleep( 3000 );
Debug(_T("-Reconnect failed(socket)\n"));
}
while(TRUE)
{
if(Connect())
break;
Sleep( 2000 );
Create();
}
return TRUE;
}
void cClientSocket::CloseSocket()
{
if( m_socket != INVALID_SOCKET )
{
shutdown( m_socket, SD_BOTH );
closesocket( m_socket );
}
SetSocketHandle( INVALID_SOCKET );
}
//////////////////////////////////////////////////////////////////////
// Socket Control
//////////////////////////////////////////////////////////////////////
BOOL cClientSocket::SetSocketOption()
{
BOOL bSockOpt = TRUE;
if( setsockopt( m_socket,
IPPROTO_TCP,
TCP_NODELAY,
reinterpret_cast<char*>(&bSockOpt),
sizeof(bSockOpt) ) == SOCKET_ERROR )
{
CloseSocket();
return FALSE;
}
LINGER lingerStruct;
lingerStruct.l_onoff = 1;
lingerStruct.l_linger = 0;
if( setsockopt( m_socket,
SOL_SOCKET,
SO_LINGER,
reinterpret_cast<char*>(&lingerStruct),
sizeof(lingerStruct) ) == SOCKET_ERROR )
{
CloseSocket();
return FALSE;
}
return TRUE;
}
BOOL cClientSocket::Send( const uint8 *buffer, const uint32 length )
{
if( m_socket != INVALID_SOCKET )
{
int32 bytesSent = 0, totalSent = 0;
while( totalSent != length )
{
bytesSent = send( m_socket,
const_cast<char*>(reinterpret_cast<const char*>(buffer) + totalSent),
(length-totalSent),
0 );
if( (bytesSent == SOCKET_ERROR) && (WSAGetLastError() != WSAEWOULDBLOCK) )
{
CloseSocket();
return FALSE;
}
totalSent += bytesSent;
}
return TRUE;
}
CloseSocket();
return FALSE;
}
BOOL cClientSocket::Receive( uint8* buffer, uint32& length )
{
length = recv( m_socket,
reinterpret_cast<char*>(buffer),
length,
0 );
if( (length == SOCKET_ERROR) || (length <= 0) ) return FALSE;
return TRUE;
}
void cClientSocket::Process()
{
while( TRUE )
{
if( Connect() )
break;
Sleep( 1000 );
}
const uint32 BUFFERLEN = cSingleton<cSystem>::GetInstance()->GetPacket();
uint32 recvBytes = 0;
uint8* receiveBuffer = new uint8[BUFFERLEN];
while( TRUE )
{
recvBytes = BUFFERLEN;
if( Receive( receiveBuffer, recvBytes ) )
{
OnReceived( reinterpret_cast<uint8*>(receiveBuffer), recvBytes ); // virtual
}
else
{
// Reconnect
Reconnect();
continue;
}
}
delete []receiveBuffer;
}
@@ -0,0 +1,52 @@
// cClientSocket.h: interface for the cClientSocket class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include "cBaseThread.h"
class cClientSocket : public cBaseThread
{
public:
cClientSocket();
virtual ~cClientSocket();
void Init();
void Destroy();
public:
BOOL Startup();
void Cleanup();
void CloseSocket();
public:
SOCKET GetSocketHandle() { return m_socket; }
void SetSocketHandle( SOCKET socket ) { m_socket = socket; }
BOOL SetSocketOption();
public:
BOOL Create();
BOOL Connect( const TCHAR *IP = NULL, const uint16 port = 0 );
BOOL Reconnect();
public:
BOOL Send( const uint8 *buffer, const uint32 length );
BOOL Receive( uint8* buffer, uint32& length );
protected:
virtual void OnConnected() {}
virtual void OnDisconnected() {}
virtual void OnReceived( uint8* buffer, const uint32 length ) {}
protected:
virtual void Process();
protected:
SOCKADDR_IN m_sockAddr;
BOOL m_connected;
SOCKET m_socket;
};
@@ -0,0 +1,73 @@
// cCommandQueue.cpp: implementation of the cCommandQueue class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "cIocpContext.h"
#include "cCommandQueue.h"
#include "cCommandQueueElem.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cCommandQueue::cCommandQueue(const uint32 maxCount)
{
m_pooler.CreatePool(100, maxCount);
}
cCommandQueue::~cCommandQueue()
{
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
void cCommandQueue::PushCommand( const cIocpContext* iocpContext,
const uint32 command,
const uint8* buffer,
const uint32 length )
{
cCommandQueueElem* element = m_pooler.Pop();
if( !element )
{
Debug( _T("LS system :: not enough command queue #1\n") );
return;
}
if( element->CopyData( iocpContext,
command,
buffer,
length ) )
{
Enqueue( reinterpret_cast<DWORD>(element), sizeof(cCommandQueueElem));
}
}
void cCommandQueue::PushCommand( const uint32 ID,
const uint32 command,
const uint8* buffer,
const uint32 length )
{
cCommandQueueElem* element = m_pooler.Pop();
if( !element )
{
Debug( _T("LS system :: not enough command queue #2\n") );
return;
}
if( element->CopyData( ID,
command,
buffer,
length ) )
{
Enqueue( reinterpret_cast<DWORD>(element), sizeof(cCommandQueueElem));
}
}
void cCommandQueue::Free( cCommandQueueElem* element )
{
m_pooler.Push(element);
}
@@ -0,0 +1,31 @@
#pragma once
#include "cIocpQueue.h"
#include "../include/MemPooler.h"
class cIocpContext;
class cCommandQueueElem;
class cCommandQueue : public cIocpQueue
{
public:
cCommandQueue(const uint32 maxCount);
virtual ~cCommandQueue();
public:
void PushCommand( const cIocpContext* iocpContext,
const uint32 command,
const uint8* buffer = NULL,
const uint32 length = 0 );
void PushCommand( const uint32 ID,
const uint32 command,
const uint8* buffer = NULL,
const uint32 length = 0 );
void Free( cCommandQueueElem* element );
protected:
MemPooler<cCommandQueueElem> m_pooler;
};
@@ -0,0 +1,72 @@
// cCommandQueueElemElem.cpp: implementation of the cCommandQueueElemElem class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cIocpContext.h"
#include "cCommandQueueElem.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cCommandQueueElem::cCommandQueueElem()
{
Init();
}
cCommandQueueElem::~cCommandQueueElem()
{
Destroy();
}
void cCommandQueueElem::Init()
{
m_ID = 0;
m_command = 0;
m_context = NULL;
}
void cCommandQueueElem::Destroy()
{
m_ID = 0;
m_command = 0;
m_context = NULL;
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
BOOL cCommandQueueElem::CopyData( const cIocpContext* iocpContext,
const uint32 command,
const uint8* buffer,
const uint32 length )
{
if( cBaseQueueElem::CopyData( buffer, length ) )
{
m_context = const_cast<cIocpContext*>(iocpContext);
m_ID = 0;
m_command = command;
return TRUE;
}
return FALSE;
}
BOOL cCommandQueueElem::CopyData( const uint32 ID,
const uint32 command,
const uint8* buffer,
const uint32 length )
{
if( cBaseQueueElem::CopyData( buffer, length ) )
{
m_context = NULL;
m_ID = ID;
m_command = command;
return TRUE;
}
return FALSE;
}
@@ -0,0 +1,38 @@
#pragma once
#include "cBaseQueueElem.h"
class cCommandQueueElem : public cBaseQueueElem
{
public:
cCommandQueueElem();
virtual ~cCommandQueueElem();
void Init();
void Destroy();
public:
BOOL CopyData( const cIocpContext* iocpContext,
const uint32 command,
const uint8* buffer = NULL,
const uint32 length = 0 );
BOOL CopyData( const uint32 ID,
const uint32 command,
const uint8* buffer = NULL,
const uint32 length = 0 );
void SetContext( cIocpContext* iocpContext ) { m_context = iocpContext; }
public:
IIocpContext* GetContext() { return m_context; }
const uint32 GetID() { return m_ID; }
const uint32 GetCommand() { return m_command; }
const uint32 GetLength() { return cBaseQueueElem::GetLength(); }
const uint8* GetData() { return cBaseQueueElem::GetData(); }
private:
uint32 m_ID;
uint32 m_command;
cIocpContext* m_context;
};
@@ -0,0 +1,81 @@
// cCommandThread.cpp: implementation of the cCommandThread class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cIocpContext.h"
#include "cCommandQueue.h"
#include "cCommandQueueElem.h"
#include "cCommandThread.h"
#include "cSystem.h"
#include "../include/cSingleton.h"
#include <iostream>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cCommandThread::cCommandThread()
{
Init();
}
cCommandThread::~cCommandThread()
{
Destroy();
}
void cCommandThread::Init()
{
}
void cCommandThread::Destroy()
{
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
void cCommandThread::Process()
{
cCommandQueue* commandQueue = cSingleton<cSystem>::GetInstance()->GetCommandQueue();
if( !commandQueue ) return;
Trace( _T("CommandThread :: %lu\r\n"), GetCurrentThreadId() );
IProcessor* processor = cSingleton<cSystem>::GetInstance()->GetProcessor();
if( !processor ) return;
processor->SetCountPointer( commandQueue->m_count );
cCommandQueueElem* command = NULL;
while( !IsTerminated() )
{
command = reinterpret_cast<cCommandQueueElem*>(commandQueue->Dequeue());
if( command )
{
// process command
if( command->GetContext() )
{
processor->Process( command->GetContext(),
command->GetCommand(),
command->GetData(),
command->GetLength() );
}
else
{
processor->Process( command->GetID(),
command->GetCommand(),
command->GetData(),
command->GetLength() );
}
commandQueue->Free( command );
}
}
}
@@ -0,0 +1,19 @@
#pragma once
#include "cBaseThread.h"
class cCommandQueue;
class cCommandThread : public cBaseThread
{
public:
cCommandThread();
virtual ~cCommandThread();
void Init();
void Destroy();
protected:
virtual void Process();
};
@@ -0,0 +1,81 @@
// cCommunicator.cpp: implementation of the cCommunicator class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cCommandQueue.h"
#include "cConnectorQueue.h"
#include "cCommunicator.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cCommunicator::cCommunicator(const uint32 maxCount)
{
Init(maxCount);
}
cCommunicator::~cCommunicator()
{
Destroy();
}
void cCommunicator::Init(const uint32 maxCount)
{
CreateCommandQueue(maxCount);
CreateConnectorQueue();
}
void cCommunicator::Destroy()
{
DestroyCommandQueue();
DestroyConnectorQueue();
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
BOOL cCommunicator::CreateCommandQueue(const uint32 maxCount, const uint32 timeout)
{
m_commandQueue = new cCommandQueue(maxCount);
if( m_commandQueue )
{
m_commandQueue->Startup(timeout);
return TRUE;
}
return FALSE;
}
BOOL cCommunicator::CreateConnectorQueue()
{
m_connectorQueue = new cConnectorQueue;
if( m_connectorQueue )
{
m_connectorQueue->Startup();
return TRUE;
}
return FALSE;
}
void cCommunicator::DestroyCommandQueue()
{
if( m_commandQueue )
{
delete m_commandQueue;
m_commandQueue = NULL;
}
}
void cCommunicator::DestroyConnectorQueue()
{
if( m_connectorQueue )
{
delete m_connectorQueue;
m_connectorQueue = NULL;
}
}
@@ -0,0 +1,29 @@
#pragma once
class cCommandQueue;
class cConnectorQueue;
class cCommunicator
{
public:
cCommunicator(const uint32 maxCount);
virtual ~cCommunicator();
void Init(const uint32 maxCount);
void Destroy();
protected:
BOOL CreateCommandQueue(const uint32 maxCount, const uint32 timeout=INFINITE);
BOOL CreateConnectorQueue();
void DestroyCommandQueue();
void DestroyConnectorQueue();
public:
cCommandQueue* GetCommandQueue() { return m_commandQueue; }
cConnectorQueue* GetConnectorQueue() { return m_connectorQueue; }
private:
cCommandQueue* m_commandQueue;
cConnectorQueue* m_connectorQueue;
};
+160
View File
@@ -0,0 +1,160 @@
// cConnector.cpp: implementation of the cConnector class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cPacket.h"
#include "cBuffer.h"
#include "cSystem.h"
#include "cConnector.h"
#include "../include/cSingleton.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cConnector::cConnector() : m_ID(-1), m_sequence(0), m_packet(NULL)
{
Init();
}
cConnector::~cConnector()
{
Destroy();
}
void cConnector::Init()
{
uint32 maxPacket = cSingleton<cSystem>::GetInstance()->GetPacket();
uint32 encoding = cSingleton<cSystem>::GetInstance()->GetEncoding();
m_packet = new cPacket( encoding );
m_storage.Create( maxPacket * 4 );
m_temporary.Create( maxPacket * 4 );
}
void cConnector::Destroy()
{
if(m_packet)
{
delete m_packet;
m_packet = NULL;
}
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
BOOL cConnector::SendPacket( const uint32 command,
const uint8* buffer,
const uint32 length )
{
m_packet->Make( static_cast<uint16>(command),
buffer,
static_cast<uint16>(length),
static_cast<uint8>(GetSequence()) );
return Send( m_packet->GetBuffer(), m_packet->GetLength() );
}
void cConnector::OnConnected()
{
cSystem* system = cSingleton<cSystem>::GetInstance();
PushCommand(
system->GetConnectEvent(),
NULL,
0 );
m_sequence = 0;
}
void cConnector::OnDisconnected()
{
cSystem* system = cSingleton<cSystem>::GetInstance();
PushCommand(
system->GetDisconnectEvent(),
NULL,
0 );
}
void cConnector::OnReceived( uint8* buffer, const uint32 length )
{
// 임시버퍼에 보관된 데이타와 현재받은 데이타를 복사한다
if( !m_temporary.Copy( m_storage.GetBuffer(), m_storage.GetLength() ) )
{
return;
}
if( !m_temporary.Append( buffer, length ) )
{
return;
}
m_storage.Erase();
// 임시버퍼에 저장된 패킷을 검사하고 프로토콜 별로 나누어서 command queue에 push
CheckPacket( m_temporary.GetBuffer(), m_temporary.GetLength() );
}
void cConnector::CheckPacket( uint8* buffer, uint32 length )
{
// 패킷의 유효성 검사
if( length < sizeof(cHeader) )
{
// 헤더보다 작은 패킷이 들어왔을 경우 처리하지 않는다
m_storage.Copy( buffer, length );
return;
}
// 헤더정보 검사
cHeader* header = reinterpret_cast<cHeader*>(buffer);
//if( !header->IsPerfect() ) // 2011-02-25 youngdie, 유효성 검사 삭제
//{
// // 잘못된 헤더가 들어왔을때 패킷을 drop한다
// return;
//}
// 패킷 헤더에 따른 길이 검사
uint32 packetLength = sizeof(cHeader) + header->GetPayload();
if( length < packetLength ) // 패킷길이가 잘려서 들어왔다
{
// 저장하고 리턴
m_storage.Copy( buffer, length );
}
else if( length == packetLength ) // 패킷길이가 정확하게 들어왔다
{
PushCommand( header->GetCommand(),
buffer + sizeof(cHeader),
header->GetPayload() );
}
else if( length > packetLength ) // 패킷길이가 붙어서 들어왔다
{
PushCommand( header->GetCommand(),
buffer + sizeof(cHeader),
header->GetPayload() );
// 다음 버퍼 포인터로 이동하여 재검사
CheckPacket( buffer + packetLength, length - packetLength );
}
}
void cConnector::PushCommand( uint32 command, uint8* buffer, uint32 length )
{
// 받은 패킷을 Command큐에 입력한다
cCommandQueue* commandQueue = cSingleton<cSystem>::GetInstance()->GetCommandQueue();
if( commandQueue )
{
commandQueue->PushCommand( GetIdentity(),
command,
buffer,
static_cast<uint16>(length) );
}
}
+45
View File
@@ -0,0 +1,45 @@
#pragma once
#include "cPacket.h"
#include "cBuffer.h"
#include "cClientSocket.h"
class cConnector : public cClientSocket
{
public:
cConnector();
virtual ~cConnector();
void Init();
void Destroy();
public:
void SetIdentity( const uint32 ID ) { m_ID = ID; }
const uint32 GetIdentity() { return m_ID; }
const uint32 GetSequence()
{
if(m_sequence >= 0xff) m_sequence = 0;
return ++m_sequence;
}
BOOL SendPacket( const uint32 command,
const uint8* buffer,
const uint32 length );
protected:
virtual void OnConnected();
virtual void OnDisconnected();
virtual void OnReceived( uint8* buffer, const uint32 length );
void CheckPacket( uint8* buffer, uint32 length );
void PushCommand( uint32 command, uint8* buffer, uint32 length );
private:
uint32 m_ID;
uint32 m_sequence;
cPacket *m_packet;
cBuffer m_storage;
cBuffer m_temporary;
};
@@ -0,0 +1,126 @@
// cConnectorManager.cpp: implementation of the cConnectorManager class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cConnectorQueueElem.h"
#include "cConnectorManager.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cConnectorManager::cConnectorManager()
{
Init();
}
cConnectorManager::~cConnectorManager()
{
Destroy();
}
void cConnectorManager::Init()
{
}
void cConnectorManager::Destroy()
{
cConnector* connector = NULL;
for( CONNECTORS::iterator it = m_connectors.begin() ; it != m_connectors.end() ; ++it )
{
connector = it->second;
delete connector;
}
m_connectors.clear();
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
void cConnectorManager::Execute( cConnectorQueueElem* element )
{
cConnector* connector = Get( element->GetID() );
if( connector )
{
connector->SendPacket( element->GetCommand(),
element->GetData(),
element->GetLength() );
}
}
BOOL cConnectorManager::AddConnector(
const uint32 ID,
const TCHAR* IP,
const uint16 port )
{
cConnector* connector = Get( ID );
if( connector ) return FALSE;
connector = new cConnector;
if( connector )
{
connector->SetIdentity( ID );
if( !connector->Startup() )
{
delete connector;
return FALSE;
}
if( !connector->Create() )
{
delete connector;
return FALSE;
}
if( !connector->Connect( IP, port ) )
{
delete connector;
return FALSE;
}
if( !connector->StartThread() )
{
delete connector;
return FALSE;
}
m_connectors[ID] = connector;
return TRUE;
}
return FALSE;
}
BOOL cConnectorManager::DelConnector( const uint32 ID )
{
cConnector* connector = Remove( ID );
if( connector )
{
delete connector;
return TRUE;
}
return FALSE;
}
cConnector* cConnectorManager::Get( const uint32 ID )
{
CONNECTORS::iterator it = m_connectors.find( ID );
return ( it != m_connectors.end() ) ? it->second : NULL;
}
cConnector* cConnectorManager::Remove( const uint32 ID )
{
CONNECTORS::iterator it = m_connectors.find( ID );
if( it != m_connectors.end() )
{
cConnector* connector = it->second;
m_connectors.erase( it );
return connector;
}
return NULL;
}
@@ -0,0 +1,32 @@
#pragma once
#include "cConnector.h"
#include <map>
class cConnectorQueueElem;
class cConnectorManager
{
public:
cConnectorManager();
virtual ~cConnectorManager();
void Init();
void Destroy();
public:
void Execute( cConnectorQueueElem* element );
BOOL AddConnector( const uint32 ID,
const TCHAR* IP,
const uint16 port );
BOOL DelConnector( const uint32 ID );
protected:
cConnector* Get( const uint32 ID );
cConnector* Remove( const uint32 ID );
protected:
typedef std::map<uint32,cConnector*> CONNECTORS;
CONNECTORS m_connectors;
};
@@ -0,0 +1,50 @@
// cConnectorQueue.cpp: implementation of the cConnectorQueue class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cSystem.h"
#include "cConnectorQueue.h"
#include "cConnectorQueueElem.h"
#include "../include/cSingleton.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cConnectorQueue::cConnectorQueue()
{
m_pooler.CreatePool(100, cSingleton<cSystem>::GetInstance()->GetPool());
}
cConnectorQueue::~cConnectorQueue()
{
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
void cConnectorQueue::PushCommand( const uint32 ID,
const uint32 command,
const uint8* buffer,
const uint16 length )
{
cConnectorQueueElem* element = m_pooler.Pop();
if( element )
{
if( element->CopyData( ID,
command,
buffer,
length ) )
{
Enqueue( reinterpret_cast<DWORD>(element), sizeof(cConnectorQueueElem) );
}
}
}
void cConnectorQueue::Free( cConnectorQueueElem* element )
{
m_pooler.Push(element);
}
@@ -0,0 +1,24 @@
#pragma once
#include "cIocpQueue.h"
#include "../include/MemPooler.h"
class cConnectorQueueElem;
class cConnectorQueue : public cIocpQueue
{
public:
cConnectorQueue();
virtual ~cConnectorQueue();
public:
void PushCommand( const uint32 ID,
const uint32 command,
const uint8* buffer = NULL,
const uint16 length = 0 );
void Free( cConnectorQueueElem* element );
protected:
MemPooler<cConnectorQueueElem> m_pooler;
};
@@ -0,0 +1,54 @@
// cConnectorQueueElem.cpp: implementation of the cConnectorQueueElem class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cConnectorQueueElem.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cConnectorQueueElem::cConnectorQueueElem()
{
Init();
}
cConnectorQueueElem::~cConnectorQueueElem()
{
Destroy();
}
void cConnectorQueueElem::Init()
{
m_ID = 0;
m_command = 0;
}
void cConnectorQueueElem::Destroy()
{
m_ID = 0;
m_command = 0;
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
BOOL cConnectorQueueElem::CopyData( const uint32 ID,
const uint32 command,
const uint8* buffer,
const uint32 length )
{
if( cBaseQueueElem::CopyData( buffer, length ) )
{
m_ID = ID;
m_command = command;
return TRUE;
}
return FALSE;
}
@@ -0,0 +1,26 @@
#pragma once
#include "cBaseQueueElem.h"
class cConnectorQueueElem : public cBaseQueueElem
{
public:
cConnectorQueueElem();
virtual ~cConnectorQueueElem();
void Init();
void Destroy();
public:
BOOL CopyData( const uint32 ID,
const uint32 command,
const uint8* buffer = NULL,
const uint32 length = 0 );
uint32 GetID() { return m_ID; }
uint32 GetCommand() { return m_command; }
private:
uint32 m_ID;
uint32 m_command;
};
@@ -0,0 +1,63 @@
// cConnectorThread.cpp: implementation of the cConnectorThread class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cConnectorQueue.h"
#include "cConnectorQueueElem.h"
#include "cConnectorThread.h"
#include "cConnectorManager.h"
#include "cSystem.h"
#include "../include/cSingleton.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cConnectorThread::cConnectorThread()
{
Init();
}
cConnectorThread::~cConnectorThread()
{
Destroy();
}
void cConnectorThread::Init()
{
}
void cConnectorThread::Destroy()
{
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
void cConnectorThread::Process()
{
cConnectorQueue* connectorQueue = cSingleton<cSystem>::GetInstance()->GetConnectorQueue();
if( !connectorQueue ) return;
Trace( _T("ConnectorThread :: %lu\n"), GetCurrentThreadId() );
cNetwork* network = cSingleton<cSystem>::GetInstance()->GetNetwork();
cConnectorQueueElem* command = NULL;
while( !IsTerminated() )
{
command = reinterpret_cast<cConnectorQueueElem*>(connectorQueue->Dequeue());
if( command )
{
// process command
network->SendConnector( command );
// delete a command
connectorQueue->Free( command );
}
}
}
@@ -0,0 +1,17 @@
#pragma once
#include "cBaseThread.h"
class cConnectorThread : public cBaseThread
{
public:
cConnectorThread();
virtual ~cConnectorThread();
void Init();
void Destroy();
protected:
virtual void Process();
};
+132
View File
@@ -0,0 +1,132 @@
#include "StdAfx.h"
#include "cSystem.h"
#include "cDoubleOV.h"
#include "../include/cSingleton.h"
enum WSASendingStates
{
WSA_SENDING = 1,
WSA_WAITING
};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cDoubleOV::cDoubleOV(void) : m_iterator(0), m_sending(WSA_WAITING)
{
Init();
}
cDoubleOV::~cDoubleOV(void)
{
Destroy();
}
void cDoubleOV::Init()
{
uint32 length = cSingleton<cSystem>::GetInstance()->GetPacket() * 4;
m_iocpOV[0].Alloc( length );
m_iocpOV[1].Alloc( length );
}
void cDoubleOV::Destroy()
{
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
void cDoubleOV::Reset()
{
m_iterator = 0;
m_iocpOV[0].Clean();
m_iocpOV[1].Clean();
}
uint32 cDoubleOV::GetDataLength()
{
return m_iocpOV[GetIterator()].GetDataLength();
}
uint32 cDoubleOV::GetBufferLength()
{
return m_iocpOV[GetIterator()].GetBufferLength();
}
BOOL cDoubleOV::IsSending()
{
return (WSA_SENDING == m_sending) ? TRUE : FALSE;
}
void cDoubleOV::Alloc(const uint32 bufferLength)
{
m_iocpOV[GetIterator()].Alloc(bufferLength);
}
void cDoubleOV::CopyBuffer(const uint8* buffer, const uint32 bufferLength)
{
m_iocpOV[GetIterator()].CopyBuffer(buffer, bufferLength);
}
BOOL cDoubleOV::AppendBuffer(const uint8* buffer, const uint32 bufferLength)
{
uint32 it = GetIterator();
m_iocpOV[it].AppendBuffer(buffer, bufferLength);
if(m_iocpOV[it].GetDataLength() >= cSingleton<cSystem>::GetInstance()->GetPacket())
{
// 보낼 때가 됨
return FALSE;
}
return TRUE;
}
BOOL cDoubleOV::Appendable(const uint32 bufferLength)
{
uint32 it = GetIterator();
uint32 dataLength = m_iocpOV[it].GetDataLength();
uint32 maxLength = m_iocpOV[it].GetBufferLength();
if((dataLength+bufferLength) >= maxLength)
{
// 패킷이 오버됨
return FALSE;
}
return TRUE;
}
cIocpOv* cDoubleOV::Pop()
{
if(WSA_WAITING == m_sending)
{
cIocpOv* iocpOvl = &(m_iocpOV[m_iterator]);
if(iocpOvl->GetDataLength() > 0)
{
if(0 == m_iterator)
{
InterlockedExchange(&m_iterator, 1);
}
else
{
InterlockedExchange(&m_iterator, 0);
}
InterlockedCompareExchange(&m_sending, WSA_SENDING, WSA_WAITING);
return iocpOvl;
}
}
return NULL;
}
void cDoubleOV::Push(cIocpOv* iocpOvl)
{
iocpOvl->Clean();
InterlockedCompareExchange(&m_sending, WSA_WAITING, WSA_SENDING);
}
uint32 cDoubleOV::GetIterator()
{
return m_iterator;
}
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#include "cIocpOv.h"
class cDoubleOV
{
public:
cDoubleOV(void);
~cDoubleOV(void);
void Init();
void Destroy();
public:
void Reset();
uint32 GetDataLength();
uint32 GetBufferLength();
BOOL IsSending();
void Alloc(const uint32 bufferLength);
void CopyBuffer(const uint8* buffer, const uint32 bufferLength);
BOOL AppendBuffer(const uint8* buffer, const uint32 bufferLength);
BOOL Appendable(const uint32 bufferLength);
cIocpOv* Pop();
void Push(cIocpOv* iocpOvl);
protected:
uint32 GetIterator();
protected:
cIocpOv m_iocpOV[2];
uint32 m_iterator;
volatile uint32 m_sending;
};
+183
View File
@@ -0,0 +1,183 @@
#include "stdafx.h"
#include "cEncrypt.h"
// cEncrypt
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cEncrypt::cEncrypt() : m_arrayLen(4028)
{
m_arrayBuffer = new uint8[m_arrayLen];
}
cEncrypt::~cEncrypt()
{
if(m_arrayBuffer)
{
delete []m_arrayBuffer;
m_arrayBuffer = NULL;
}
}
uint32 cEncrypt::Compress(const uint8 *source, uint32 sourceLen, uint8 *destination)
{
uint32 index = 0;
uint32 zeroCount = 0;
uint32 zeroBit = 0;
uint32 bitArrayCount = 0;
uint32 usedBytes = 0;
uint8 bit = 0;
ZeroMemory(m_arrayBuffer, m_arrayLen);
for(uint32 i = 0; i < sourceLen; ++i)
{
if(0 == source[i])
{
++zeroCount;
zeroBit = i % 8;
bitArrayCount = i >> 3;
bit = 1;
bit = bit << zeroBit;
m_arrayBuffer[bitArrayCount] = m_arrayBuffer[bitArrayCount] | bit;
if(usedBytes < bitArrayCount) usedBytes = bitArrayCount;
}
else
{
// 1바이트씩 복사
destination[index++] = source[i];
}
}
if(zeroCount > 0) ++usedBytes;
memmove(destination+sizeof(uint16)+usedBytes, destination, sourceLen-zeroCount);
CopyMemory(destination, &usedBytes, sizeof(uint16)); // + 널값정보에 이용되는 버퍼 길이 2Byte
CopyMemory(destination+sizeof(uint16), m_arrayBuffer, usedBytes);
return (sizeof(uint16) + usedBytes + sourceLen - zeroCount);
}
uint32 cEncrypt::Decompress(const uint8 *source, uint32 sourceLen, uint8 *destination)
{
uint16 bitArrayCount = 0;
uint32 originalLen = 0;
uint32 bufferCount = 0;
charBit *tempByte;
CopyMemory(&bitArrayCount, source, sizeof(unsigned short));
originalLen = sourceLen-sizeof(uint16);
bufferCount = originalLen = originalLen - bitArrayCount;
ZeroMemory(m_arrayBuffer, m_arrayLen);
CopyMemory(m_arrayBuffer, source+sizeof(uint16), bitArrayCount);
const uint8* lpData = (source + sizeof(uint16) + bitArrayCount);
uint32 indexSrc = 0, indexDst = 0;
for(uint32 i=0; i < bitArrayCount; ++i)
{
tempByte = reinterpret_cast<charBit*>(&m_arrayBuffer[i]);
if(tempByte->v1==0)
{
if(indexSrc < bufferCount)
destination[indexDst++] = lpData[indexSrc++];
}
else
{
destination[indexDst++] = 0;
++originalLen;
}
if(tempByte->v2==0)
{
if(indexSrc < bufferCount)
destination[indexDst++] = lpData[indexSrc++];
}
else
{
destination[indexDst++] = 0;
++originalLen;
}
if(tempByte->v3==0)
{
if(indexSrc < bufferCount)
destination[indexDst++] = lpData[indexSrc++];
}
else
{
destination[indexDst++] = 0;
++originalLen;
}
if(tempByte->v4==0)
{
if(indexSrc < bufferCount)
destination[indexDst++] = lpData[indexSrc++];
}
else
{
destination[indexDst++] = 0;
++originalLen;
}
if(tempByte->v5==0)
{
if(indexSrc < bufferCount)
destination[indexDst++] = lpData[indexSrc++];
}
else
{
destination[indexDst++] = 0;
++originalLen;
}
if(tempByte->v6==0)
{
if(indexSrc < bufferCount)
destination[indexDst++] = lpData[indexSrc++];
}
else
{
destination[indexDst++] = 0;
++originalLen;
}
if(tempByte->v7==0)
{
if(indexSrc < bufferCount)
destination[indexDst++] = lpData[indexSrc++];
}
else
{
destination[indexDst++] = 0;
++originalLen;
}
if(tempByte->v8==0)
{
if(indexSrc < bufferCount)
destination[indexDst++] = lpData[indexSrc++];
}
else
{
destination[indexDst++] = 0;
++originalLen;
}
}
// 아직 데이타가 남아있으면 넣어준다
// (m_arrayBuffer 처리 이후에도 값이 남아있는경우는 (byte단위로)NULL값 없이 연속으로 데이터가 있는경우이다)
for( ; indexSrc < bufferCount;)
{
destination[indexDst++] = lpData[indexSrc++];
}
return originalLen;
}
+42
View File
@@ -0,0 +1,42 @@
#pragma once
// encrypt & compress
/*
* [압축]
* - 버퍼 구조 : 3개의 층으로 되어있다.
*
* -------------------------------------------------------------
* 1) | 널 값을 가지는 위치(BYTE)정보를 가지는 버퍼의 크기(2Byte) |
* -------------------------------------------------------------
* 2) | 널 값의 위치 정보를 가지고 있는 버퍼. 크기는 가변(nByte) |
* ------------------------------------------------------------
* 3) | 널 값을 없앤 데이타. |
* -------------------------------------------------------------
*/
class cEncrypt
{
public:
cEncrypt();
virtual ~cEncrypt();
public:
struct charBit
{
uint8 v1:1;
uint8 v2:1;
uint8 v3:1;
uint8 v4:1;
uint8 v5:1;
uint8 v6:1;
uint8 v7:1;
uint8 v8:1;
};
// 압축
uint32 Compress(const uint8 *source, uint32 sourceLen, uint8 *destination);
// 압축해제
uint32 Decompress(const uint8 *source, uint32 sourceLen, uint8 *destination);
protected:
uint32 m_arrayLen;
uint8* m_arrayBuffer;
};
+32
View File
@@ -0,0 +1,32 @@
#pragma once
// packet header
class cHeader
{
public:
cHeader()
{
m_payload = 0;
m_command = 0;
m_sequence = 0;
}
public:
void SetHeader( const uint16 payload = 0, const uint16 command = 0, const uint8 sequence = 0 )
{
m_payload = payload;
m_command = command;
m_sequence = sequence;
}
BOOL IsPerfect(const uint8 sequence) { return (sequence == m_sequence) ? TRUE : FALSE; }
uint16 GetPayload() { return m_payload; }
uint16 GetCommand() { return m_command; }
uint8 GetSequence() { return m_sequence; }
protected:
uint16 m_payload;
uint16 m_command;
uint8 m_sequence;
};
+76
View File
@@ -0,0 +1,76 @@
#include "stdafx.h"
#include "cIOCP.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cIOCP::cIOCP(void)
{
Init();
}
cIOCP::~cIOCP(void)
{
Destroy();
}
void cIOCP::Init()
{
m_completionPort = NULL;
}
void cIOCP::Destroy()
{
Close();
}
//////////////////////////////////////////////////////////////////////
// Operation
//////////////////////////////////////////////////////////////////////
// create new I/O completion port
BOOL cIOCP::Create()
{
m_completionPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE,
NULL,
0,
0 );
return (m_completionPort ? TRUE : FALSE);
}
// destroy I/O completion port
void cIOCP::Close()
{
if( m_completionPort )
{
CloseHandle( m_completionPort );
m_completionPort = NULL;
}
}
// associate an instance
BOOL cIOCP::AssocInstance( HANDLE socket, DWORD ioKey )
{
HANDLE hIocpPort = CreateIoCompletionPort( socket,
m_completionPort,
ioKey,
0 );
return (hIocpPort ? TRUE : FALSE);
}
// dequeue an I/O completion packet from IOCP
BOOL cIOCP::GetIocpStatus( LPDWORD bytesTransferred,
PULONG completionKey,
LPOVERLAPPED* overlapped,
DWORD milliseconds )
{
return GetQueuedCompletionStatus( m_completionPort,
bytesTransferred,
completionKey,
overlapped,
milliseconds ) ? TRUE : FALSE;
}
+26
View File
@@ -0,0 +1,26 @@
#pragma once
class cIocpOperation;
class cIOCP
{
public:
cIOCP(void);
~cIOCP(void);
void Init();
void Destroy();
public:
BOOL Create();
void Close();
BOOL AssocInstance( HANDLE socket, DWORD ioKey );
BOOL GetIocpStatus( LPDWORD bytesTransferred,
PULONG completionKey,
LPOVERLAPPED* overlapped,
DWORD milliseconds = INFINITE );
protected:
HANDLE m_completionPort;
};
@@ -0,0 +1,53 @@
// cIocpContext.cpp: implementation of the cIocpContext class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cSystem.h"
#include "cIocpContext.h"
#include "../include/cSingleton.h"
uint32 cIocpContext::ENTITY = 0;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cIocpContext::cIocpContext() : m_active(FALSE), m_associated(FALSE), m_portId(0), m_sequence(1)
{
Init();
}
cIocpContext::~cIocpContext()
{
Destroy();
}
void cIocpContext::Init()
{
SetEntity(++ENTITY);
CreateStorage(cSingleton<cSystem>::GetInstance()->GetPacket() * 2);
}
void cIocpContext::Destroy()
{
}
void cIocpContext::Reset()
{
SetActive(TRUE);
SetSequence(1);
cStorage::CleanStorage();
cSocket::Reset();
}
void cIocpContext::Disconnect()
{
if(IsActive())
{
SetActive(FALSE);
cSocket::Disconnect();
}
}
@@ -0,0 +1,59 @@
// cIocpContext.h: interface for the cIocpContext class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include "cSocket.h"
#include "cStorage.h"
#include "../include/IIocpContext.h"
class cIocpContext : public IIocpContext, public cSocket, public cStorage
{
friend class cWorkerThread;
public:
cIocpContext();
~cIocpContext();
void Init();
void Destroy();
public:
virtual BOOL IsActive() { return m_active; }
virtual void SetActive( BOOL active ) { m_active = active; }
virtual void Disconnect();
virtual uint32 GetEntity() { return m_entity; }
virtual uint32 GetIP() { return m_IP; }
public:
void Reset();
void SetEntity( uint32 entity ) { m_entity = entity; }
void SetPortID( uint32 portId ) { m_portId = portId; }
void SetSequence( uint8 sequence ) { m_sequence = sequence;}
uint32 GetPortID() { return m_portId; }
//uint8 GetSequence() { return ((m_sequence+1) > 0xff) ? 1 : (m_sequence+1); }
uint8 GetSequence() { return m_sequence; }
void PopSequence()
{
if(m_sequence >= 0xff) m_sequence = 0;
++m_sequence;
}
void Associate() { m_associated = TRUE; }
BOOL IsAssociated() { return m_associated; }
private:
BOOL m_active;
BOOL m_associated;
uint32 m_entity;
uint32 m_portId;
uint8 m_sequence;
static uint32 ENTITY;
};
+96
View File
@@ -0,0 +1,96 @@
// cIocpOv.cpp: implementation of the cIocpOv class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cSystem.h"
#include "cIocpOv.h"
#include "../include/cSingleton.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cIocpOv::cIocpOv(E_IO_OPERATION iocpOP) : m_buffer(NULL), m_dataLength(0), m_bufferLength(0)
{
Init(0, iocpOP);
}
void cIocpOv::Init(const uint32 bufferLength, E_IO_OPERATION iocpOP)
{
ZeroMemory(&m_wsaBuf, sizeof(m_wsaBuf));
ZeroMemory(&m_overlapped, sizeof(WSAOVERLAPPED));
SetOperation( iocpOP );
}
void cIocpOv::Destroy()
{
if(m_buffer)
{
delete []m_buffer;
m_buffer = NULL;
}
m_dataLength = 0;
m_bufferLength = 0;
ZeroMemory(&m_wsaBuf, sizeof(m_wsaBuf));
ZeroMemory(&m_overlapped, sizeof(WSAOVERLAPPED));
}
void cIocpOv::Clean()
{
if( m_buffer )
{
m_dataLength = 0;
ZeroMemory(m_buffer, m_bufferLength);
ZeroMemory(&m_overlapped, sizeof(WSAOVERLAPPED));
}
}
//////////////////////////////////////////////////////////////////////
// iocpOP
//////////////////////////////////////////////////////////////////////
void cIocpOv::Alloc(const uint32 bufferLength)
{
uint8* tempBuffer = new uint8[ bufferLength ];
if( tempBuffer )
ZeroMemory(tempBuffer, bufferLength);
if( m_buffer )
{
CopyMemory( tempBuffer, m_buffer, m_dataLength );
delete []m_buffer;
}
m_buffer = tempBuffer;
m_bufferLength = bufferLength;
m_wsaBuf.buf = reinterpret_cast<CHAR*>(m_buffer);
m_wsaBuf.len = m_bufferLength;
}
void cIocpOv::CopyBuffer(const uint8* buffer, const uint32 bufferLength)
{
if( bufferLength >= m_bufferLength )
{
Alloc( bufferLength );
}
CopyMemory(m_wsaBuf.buf, buffer, bufferLength);
m_dataLength = bufferLength;
m_wsaBuf.len = m_dataLength;
}
void cIocpOv::AppendBuffer(const uint8* buffer, const uint32 bufferLength)
{
if( (m_dataLength+bufferLength) >= m_bufferLength )
{
Alloc( (m_dataLength+bufferLength) );
}
CopyMemory(m_wsaBuf.buf+m_dataLength, buffer, bufferLength);
m_dataLength += bufferLength;
m_wsaBuf.len = m_dataLength;
}
+38
View File
@@ -0,0 +1,38 @@
// cIocpOv.h: interface for the cIocpOv class.
//
// date : 2006.03.20, 신영욱
// note : IOCP operation에 필요한 WSAOVERLAPPED 객체와
// WSABUF 객체를 포함하고 있는 클래스
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include "cOverlapped.h"
class cIocpOv : public cOverlapped
{
public:
cIocpOv(E_IO_OPERATION iocpOP=E_IO_NONE);
public:
void Init(const uint32 bufferLength, E_IO_OPERATION iocpOP);
void Destroy();
void Clean();
public:
uint32 GetDataLength() { return m_dataLength; }
uint32 GetBufferLength() { return m_bufferLength; }
void Alloc(const uint32 bufferLength);
void CopyBuffer(const uint8* buffer, const uint32 bufferLength);
void AppendBuffer(const uint8* buffer, const uint32 bufferLength);
public:
WSABUF m_wsaBuf;
uint8* m_buffer;
uint32 m_dataLength;
uint32 m_bufferLength;
};
+100
View File
@@ -0,0 +1,100 @@
// cIocpQueue.cpp: implementation of the cIocpQueue class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "cIocpQueue.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cIocpQueue::cIocpQueue() : m_count(0), m_completionPort(NULL)
{
}
cIocpQueue::~cIocpQueue()
{
Cleanup();
}
//////////////////////////////////////////////////////////////////////
// Startup/Cleanup
//////////////////////////////////////////////////////////////////////
BOOL cIocpQueue::Startup( int32 timeout )
{
if( !m_completionPort )
{
m_completionPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE,
NULL,
0,
0 );
if( !m_completionPort ) return FALSE;
m_timeout = timeout;
return TRUE;
}
return FALSE;
}
void cIocpQueue::Cleanup()
{
if( m_completionPort )
{
CloseHandle( m_completionPort );
m_completionPort = NULL;
}
}
//////////////////////////////////////////////////////////////////////
// Enqueue/Dequeue
//////////////////////////////////////////////////////////////////////
BOOL cIocpQueue::Enqueue( const DWORD completionKey, const DWORD bytes )
{
if( m_completionPort )
{
if(PostQueuedCompletionStatus( m_completionPort,
bytes,
completionKey,
NULL ))
{
InterlockedIncrement( &m_count );
return TRUE;
}
}
return FALSE;
}
LPDWORD cIocpQueue::Dequeue()
{
DWORD bytes = 0;
return Dequeue( bytes );
}
LPDWORD cIocpQueue::Dequeue( DWORD &bytes )
{
LPDWORD completionKey = NULL;
LPOVERLAPPED overlapped = NULL;
if( m_completionPort )
{
if(GetQueuedCompletionStatus( m_completionPort,
&bytes,
reinterpret_cast<LPDWORD>(&completionKey),
&overlapped,
m_timeout ))
{
InterlockedDecrement( &m_count );
}
}
return completionKey;
}
+27
View File
@@ -0,0 +1,27 @@
#pragma once
class cIocpQueue
{
public:
cIocpQueue();
virtual ~cIocpQueue();
BOOL Startup( int32 timeout = INFINITE );
void Cleanup();
public:
LPDWORD Dequeue();
LPDWORD Dequeue( DWORD &bytes );
LONG GetCount() { return m_count; }
protected:
BOOL Enqueue( const DWORD completionKey, const DWORD bytes );
public:
volatile LONG m_count;
protected:
int32 m_timeout;
HANDLE m_completionPort;
};
+150
View File
@@ -0,0 +1,150 @@
// cModule.cpp: implementation of the cModule class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cWorkerThread.h"
#include "cCommandThread.h"
#include "cConnectorThread.h"
#include "cModule.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cModule::cModule()
{
Init();
}
cModule::~cModule()
{
Destroy();
}
void cModule::Init()
{
m_workerThread = NULL;
m_commandThread = NULL;
m_connectorThread = NULL;
}
void cModule::Destroy()
{
EndModule();
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
// thread moduleŔť ˝ĂŔŰÇŃ´Ů
BOOL cModule::StartModule( E_THREADID threadId, uint32 count )
{
switch( threadId )
{
case E_THREADID_COMMAND :
StartCommandThread( count );
break;
case E_THREADID_CONNECTOR :
StartConnectorThread( count );
break;
case E_THREADID_WORKER :
StartWorkerThread( count );
break;
}
return TRUE;
}
// thread moduleŔť ÁžˇáÇŃ´Ů
void cModule::EndModule()
{
CloseWorkerThread();
CloseCommandThread();
CloseConnectorThread();
}
//////////////////////////////////////////////////////////////////////
// thread module
//////////////////////////////////////////////////////////////////////
BOOL cModule::StartCommandThread( uint32 count )
{
CloseCommandThread();
m_commandThread = new cCommandThread[count];
if( m_commandThread )
{
for( uint32 i = 0 ; i < count; i++ )
{
if( !m_commandThread[i].StartThread() ) return FALSE;
}
return TRUE;
}
return FALSE;
}
BOOL cModule::StartWorkerThread( uint32 count )
{
CloseWorkerThread();
m_workerThread = new cWorkerThread[count];
if( m_workerThread )
{
for( uint32 i = 0 ; i < count; i++ )
{
if( !m_workerThread[i].StartThread() ) return FALSE;
}
return TRUE;
}
return FALSE;
}
BOOL cModule::StartConnectorThread( uint32 count )
{
CloseConnectorThread();
m_connectorThread = new cConnectorThread[count];
if( m_connectorThread )
{
for( uint32 i = 0 ; i < count; i++ )
{
if( !m_connectorThread[i].StartThread() ) return FALSE;
}
return TRUE;
}
return FALSE;
}
void cModule::CloseCommandThread()
{
if( m_commandThread )
{
delete []m_commandThread;
m_commandThread = NULL;
}
}
void cModule::CloseWorkerThread()
{
if( m_workerThread )
{
delete []m_workerThread;
m_workerThread = NULL;
}
}
void cModule::CloseConnectorThread()
{
if( m_connectorThread )
{
delete []m_connectorThread;
m_connectorThread = NULL;
}
}
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#include "Thread.h"
class cWorkerThread;
class cCommandThread;
class cConnectorThread;
class cModule
{
public:
cModule();
virtual ~cModule();
void Init();
void Destroy();
public:
// start/close
BOOL StartModule( E_THREADID threadId, uint32 count );
void EndModule();
protected:
// thread module
BOOL StartCommandThread( uint32 count = 1 );
BOOL StartWorkerThread( uint32 count = 2 );
BOOL StartConnectorThread( uint32 count = 1 );
void CloseCommandThread();
void CloseWorkerThread();
void CloseConnectorThread();
private:
cWorkerThread* m_workerThread;
cCommandThread* m_commandThread;
cConnectorThread* m_connectorThread;
};
+163
View File
@@ -0,0 +1,163 @@
// cNetwork.cpp: implementation of the cNetwork class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cIocpContext.h"
#include "cConnectorQueueElem.h"
#include "cIOCP.h"
#include "cSystem.h"
#include "cNetwork.h"
#include "../include/cSingleton.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cNetwork::cNetwork()
{
Init();
}
cNetwork::~cNetwork()
{
Destroy();
}
void cNetwork::Init()
{
}
void cNetwork::Destroy()
{
}
BOOL cNetwork::Startup( const uint32 maximum )
{
WSADATA WsaData;
if( WSAStartup(MAKEWORD( 2, 2 ), &WsaData) != 0 )
{
Trace( _T("WSAStartup Error :: %lu\n"), WSAGetLastError() );
return FALSE;
}
m_pooler.Create(maximum);
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
// Socket 생성
BOOL cNetwork::CreateServerSocket( uint16 port, int32 backlog, uint32& portId )
{
if(m_serverSocketManager.AddSocket(port, backlog, portId))
{
cServerSocket *serverSocket = m_serverSocketManager.GetSocket( portId );
if(serverSocket)
{
cIOCP* IOCP = cSingleton<cSystem>::GetInstance()->GetIOCP();
return IOCP->AssocInstance( reinterpret_cast<HANDLE>(serverSocket->GetSocketHandle()),
reinterpret_cast<DWORD>(serverSocket) );
return TRUE;
}
}
return FALSE;
}
// Accept요청
BOOL cNetwork::AcceptReqeust( uint32 portId )
{
// ServerSocket을 얻어낸다
cServerSocket* serverSocket = m_serverSocketManager.GetSocket( portId );
if( !serverSocket )
{
// 이 경우는 발생할 수 없다.
Information( _T("[%lu]LS system :: accept failed - critical\n"), GetCurrentThreadId() );
return FALSE;
}
// backlog만큼 Accept요청
uint32 tryCount = 0;
while( serverSocket->GetAcceptingCount() < serverSocket->GetBacklog() )
{
cIocpContext* iocpContext = m_pooler.Pop();
if( !iocpContext )
{
// 메모리 풀이 비어있다.
//Debug( _T("[%lu]LS system :: accept failed - socket pool is empty\n"), GetCurrentThreadId() );
break;
}
iocpContext->SetPortID( portId );
iocpContext->CleanOverlapped(E_IO_ACCEPT);
for( tryCount = 1 ; tryCount <= 5 ; tryCount++ )
{
if( !serverSocket->AcceptRequest( iocpContext->GetSockHandle(),
iocpContext->GetWsaBuffer(),
iocpContext->GetOverlapped(E_IO_ACCEPT) ) )
{
Debug( _T("[%lu]LS system :: socket create\n"), GetCurrentThreadId() );
iocpContext->CloseSocket();
iocpContext->CreateSocket();
}
else
{
// successful request.
break;
}
}
}
if( serverSocket->GetAcceptingCount() == 0 )
{
Debug( _T("[%lu]LS system :: empty socket\n"), GetCurrentThreadId() );
}
else
{
//Debug( _T("[%lu]LS system :: socket(%lu)\n"), GetCurrentThreadId(), serverSocket->GetAcceptingCount() );
}
return TRUE;
}
// Accept 요청이 완료된 후의 처리
void cNetwork::AcceptCompleted( uint32 portId )
{
// ServerSocket을 얻어낸다
cServerSocket* serverSocket = m_serverSocketManager.GetSocket( portId );
if( serverSocket )
{
serverSocket->DecreaseAcceptingCount();
}
}
// 모든 일을 마친 Context에 대한 처리
void cNetwork::Finish( cIocpContext* iocpContext )
{
m_pooler.Push(iocpContext);
// Accept요청이 없을 경우 요청하도록 함
const uint32 portId = iocpContext->GetPortID();
cServerSocket* serverSocket = m_serverSocketManager.GetSocket( portId );
if( serverSocket )
{
AcceptReqeust( portId );
}
}
// Connector추가
BOOL cNetwork::AddConnector( const uint32 ID, const TCHAR* IP, const uint16 port )
{
return m_connectorManager.AddConnector( ID, IP, port );
}
// Connector를 통해 전달
void cNetwork::SendConnector( cConnectorQueueElem* command )
{
m_connectorManager.Execute( command );
}
+42
View File
@@ -0,0 +1,42 @@
// cNetwork.h: interface for the cNetwork class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include <vector>
#include "cPooler.h"
#include "cConnectorManager.h"
#include "cServerSocketManager.h"
class cConnectorQueueElem;
class cNetwork
{
public:
cNetwork();
virtual ~cNetwork();
void Init();
void Destroy();
public:
BOOL Startup( const uint32 maximum );
BOOL CreateServerSocket( uint16 port, int32 backlog, uint32& portId );
BOOL AcceptReqeust( uint32 portId );
void AcceptCompleted( uint32 portId );
void Finish( cIocpContext* iocpContext );
public:
BOOL AddConnector( const uint32 ID, const TCHAR* IP, const uint16 port );
void SendConnector( cConnectorQueueElem* command );
protected:
cPooler m_pooler;
cConnectorManager m_connectorManager;
cServerSocketManager m_serverSocketManager;
};
+28
View File
@@ -0,0 +1,28 @@
#pragma once
// Operation ºÐ·ù
typedef enum E_IO_OPERATION
{
E_IO_NONE = 0,
E_IO_ACCEPT,
E_IO_RECEIVE,
E_IO_SEND,
E_IO_DISCONNECT
};
// Overlapped±¸Á¶Ã¼¿Í Operation¼³Á¤
class cOverlapped
{
public:
cOverlapped(void) { Clean(); }
public:
void Clean() { ZeroMemory( &m_overlapped, sizeof(WSAOVERLAPPED) ); }
void SetOperation( E_IO_OPERATION operation ) { m_operation = operation; }
uint8 GetOperation() { return m_operation; }
public:
WSAOVERLAPPED m_overlapped;
uint8 m_operation;
};
+132
View File
@@ -0,0 +1,132 @@
// cPacket.cpp: implementation of the cPacket class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cPacket.h"
#include "../include/Constant.h"
uint32 cPacket::m_maxLength = 1024 * 16;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cPacket::cPacket(const uint32 encoding) : m_compressor(NULL), m_decompressor(NULL), m_length(0), m_encoding(encoding)
{
m_buffer = new uint8[m_maxLength];
ZeroMemory(m_buffer, m_maxLength);
}
cPacket::~cPacket()
{
if(m_buffer)
{
delete []m_buffer;
m_buffer = NULL;
}
if(m_compressor)
{
delete []m_compressor;
m_compressor = NULL;
}
if(m_decompressor)
{
delete []m_decompressor;
m_decompressor = NULL;
}
}
BOOL cPacket::Make(const uint16 command, const uint8 *data, const uint16 length, const uint8 sequence)
{
if(0 == sequence)
{
return Pack(command, data, length, sequence);
}
switch(m_encoding)
{
case ENCRYPT_OFF: // 비압축
{
return Pack(command, data, length, sequence);
}
break;
case ENCRYPT_ON: // 압축
{
CreateCompressor();
uint32 result = cEncrypt::Compress(data, length, m_compressor);
return Pack(command, m_compressor, static_cast<uint16>(result), sequence);
}
break;
}
return FALSE;
}
BOOL cPacket::Pack(const uint16 command, const uint8 *data, const uint16 length, const uint8 sequence)
{
// 총 길이
m_length = length + sizeof(cHeader);
if(m_length < m_maxLength)
{
// Header 설정
m_header.SetHeader(length, command, sequence);
CopyMemory(m_buffer, reinterpret_cast<uint8*>(&m_header), sizeof(cHeader));
// Payload 복사
CopyMemory(m_buffer+sizeof(cHeader), data, length);
return TRUE;
}
m_length = 0;
return FALSE;
}
BOOL cPacket::Decode(uint8 *buffer, const uint32 length, const uint8 sequence, uint32& result)
{
if(0 == sequence)
return FALSE;
switch(m_encoding)
{
case ENCRYPT_OFF: // 비압축
{
return FALSE;
}
break;
case ENCRYPT_ON: // 압축해제
{
CreateDecompressor();
result = Decompress(buffer, length, m_decompressor);
return TRUE;
}
break;
}
return FALSE;
}
void cPacket::CreateCompressor()
{
if(NULL == m_compressor)
{
static uint32 length = 1024*16;
m_compressor = new uint8[length];
ZeroMemory(m_compressor, length);
}
}
void cPacket::CreateDecompressor()
{
if(NULL == m_decompressor)
{
static uint32 length = 1024*16;
m_decompressor = new uint8[length];
ZeroMemory(m_decompressor, length);
}
}
+52
View File
@@ -0,0 +1,52 @@
#pragma once
#include "cHeader.h"
#include "cEncrypt.h"
// network packet
class cPacket : public cEncrypt
{
public:
cPacket(const uint32 encoding=0);
~cPacket(void);
public:
// ÆÐŶ Á¤º¸
uint8* GetBuffer() { return m_buffer; }
uint32 GetLength() { return m_length; }
// ÆÐŶ »ý¼º
BOOL Make( const uint16 command,
const uint8 *data,
const uint16 length,
const uint8 sequence = 0 );
BOOL Pack( const uint16 command,
const uint8 *data,
const uint16 length,
const uint8 sequence = 0 );
public:
BOOL Decode( uint8 *buffer,
const uint32 length,
const uint8 sequence,
uint32& result );
const uint8* GetOutput() { return m_decompressor; }
private:
void CreateCompressor();
void CreateDecompressor();
private:
cHeader m_header;
uint8 *m_buffer;
uint8 *m_compressor, *m_decompressor;
uint32 m_length;
uint32 m_encoding;
public:
static uint32 m_maxLength;
};
+47
View File
@@ -0,0 +1,47 @@
#include "stdafx.h"
#include "cIocpContext.h"
#include "cPooler.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cPooler::cPooler(void)
{
Init();
}
cPooler::~cPooler(void)
{
Destory();
}
void cPooler::Init()
{
}
void cPooler::Destory()
{
m_contextPool.DestroyPool();
}
//////////////////////////////////////////////////////////////////////
// Operation
//////////////////////////////////////////////////////////////////////
void cPooler::Create( int32 maximum )
{
m_contextPool.CreatePool( maximum, maximum );
}
cIocpContext* cPooler::Pop()
{
return m_contextPool.Remove();
}
void cPooler::Push( cIocpContext* context )
{
m_contextPool.Push( context );
}
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include "../include/MemPooler.h"
class cIocpContext;
class cPooler
{
public:
cPooler(void);
~cPooler(void);
void Init();
void Destory();
public:
void Create( int32 maximum );
int32 GetCount() { return m_contextPool.GetCount(); }
cIocpContext* Pop();
void Push( cIocpContext* context );
private:
MemPooler<cIocpContext> m_contextPool;
};
@@ -0,0 +1,195 @@
// cServerSocket.cpp: implementation of the cServerSocket class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cServerSocket.h"
DWORD _tinet_addr(const TCHAR *IP)
{
#ifdef UNICODE
char temp[16];
uint32 nRet = 0;
nRet = WideCharToMultiByte(CP_ACP, 0, IP, _tcslen(IP), temp, 15, NULL, NULL);
temp[nRet] = 0;
return inet_addr(temp);
#else
return inet_addr(IP);
#endif
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cServerSocket::cServerSocket() : m_backlog(0), m_acceptingCount(0), m_serverSocket(INVALID_SOCKET)
{
Init();
}
cServerSocket::~cServerSocket()
{
Destroy();
}
void cServerSocket::Init()
{
}
void cServerSocket::Destroy()
{
CloseSocket();
Cleanup();
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
// initiates use of WS2_32.DLL
BOOL cServerSocket::Startup()
{
WSADATA wsaData;
if( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0 )
{
return FALSE;
}
return TRUE;
}
void cServerSocket::Cleanup()
{
WSACleanup();
}
// creates a socket
BOOL cServerSocket::CreateSocket()
{
m_serverSocket = WSASocket( AF_INET,
SOCK_STREAM,
IPPROTO_TCP,
NULL,
NULL,
WSA_FLAG_OVERLAPPED );
if( m_serverSocket != INVALID_SOCKET )
{
LINGER lingerStruct;
lingerStruct.l_onoff = 1;
lingerStruct.l_linger = 0;
if( setsockopt( m_serverSocket,
SOL_SOCKET,
SO_LINGER,
reinterpret_cast<char*>(&lingerStruct),
sizeof(lingerStruct) ) == SOCKET_ERROR )
{
CloseSocket();
return FALSE;
}
return TRUE;
}
return FALSE;
}
// close a socket
void cServerSocket::CloseSocket()
{
if( m_serverSocket != INVALID_SOCKET )
{
shutdown( m_serverSocket, SD_BOTH );
closesocket( m_serverSocket );
SetSocketHandle( INVALID_SOCKET );
}
}
// associates a local address with a socket
BOOL cServerSocket::Bind( const uint16 port, const TCHAR* IP )
{
SOCKADDR_IN sin;
sin.sin_family = AF_INET;
sin.sin_port = htons( port );
if( IP )
sin.sin_addr.s_addr = _tinet_addr( IP );
else
sin.sin_addr.s_addr = INADDR_ANY;
if( bind( m_serverSocket,
(LPSOCKADDR)&sin,
sizeof(sin) ) == SOCKET_ERROR )
{
Information( _T("[%lu]error #1(%lu)\r\n"), GetCurrentThreadId(), GetLastError() );
CloseSocket();
return FALSE;
}
BOOL on = TRUE; // AcceptEx호출 이전에 OS가 connection을 받아들이지 못하도록 설정, netstat상에 대기중인 포트가 보이지 않게됨
if( setsockopt( m_serverSocket,
SOL_SOCKET,
SO_CONDITIONAL_ACCEPT,
reinterpret_cast<char*>(&on),
sizeof(on) ) == SOCKET_ERROR )
{
// 2013-06-20 youngdie, 일부 컴퓨터에서 실행이 안되는 경우가 발생함
//Information( _T("[%lu]error #2(%lu)\r\n"), GetCurrentThreadId(), GetLastError() );
//CloseSocket();
//return FALSE;
}
return TRUE;
}
// listening for an incoming connection
BOOL cServerSocket::Listen( const int32 backlog )
{
if( listen( m_serverSocket, backlog ) == SOCKET_ERROR )
{
CloseSocket();
return FALSE;
}
m_backlog = backlog;
return TRUE;
}
// accepts an incoming connection
BOOL cServerSocket::AcceptRequest( SOCKET socket, PVOID outBuffer, LPOVERLAPPED overlapped )
{
DWORD dwBytes = 0;
BOOL bResult = AcceptEx( m_serverSocket,
socket,
outBuffer,
0, // 데이타가 들어올때까지 기다리지 않고 바로 접속을 받아들인다
sizeof(SOCKADDR_IN) + 16,
sizeof(SOCKADDR_IN) + 16,
&dwBytes,
overlapped );
if( bResult == TRUE )
{
IncreaseAcceptingCount();
return TRUE;
}
else
{
DWORD dwError = WSAGetLastError();
if( ERROR_IO_PENDING == dwError )
{
IncreaseAcceptingCount();
return TRUE;
}
Debug();
}
return FALSE;
}
@@ -0,0 +1,43 @@
// cServerSocket.h: interface for the cServerSocket class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
class cServerSocket
{
public:
cServerSocket();
virtual ~cServerSocket();
void Init();
void Destroy();
public:
BOOL Startup();
void Cleanup();
BOOL CreateSocket();
void CloseSocket();
BOOL Bind( const uint16 port, const TCHAR* IP = NULL );
BOOL Listen( const int32 backlog = SOMAXCONN );
BOOL AcceptRequest( SOCKET socket, PVOID outBuffer, LPOVERLAPPED overlapped );
public:
void SetSocketHandle( SOCKET socket ) { m_serverSocket = socket; }
SOCKET GetSocketHandle() { return m_serverSocket; }
void IncreaseAcceptingCount() { InterlockedIncrement( &m_acceptingCount ); }
void DecreaseAcceptingCount() { InterlockedDecrement( &m_acceptingCount ); }
LONG GetAcceptingCount() { return m_acceptingCount; }
LONG GetBacklog() { return m_backlog; }
protected:
LONG m_acceptingCount;
LONG m_backlog;
SOCKET m_serverSocket;
};
@@ -0,0 +1,83 @@
#include "StdAfx.h"
#include "cServerSocketManager.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cServerSocketManager::cServerSocketManager(void)
{
Init();
}
cServerSocketManager::~cServerSocketManager(void)
{
Destroy();
}
void cServerSocketManager::Init()
{
m_sockets.reserve(8);
}
void cServerSocketManager::Destroy()
{
for( uint32 i = 0 ; i < m_sockets.size() ; i++ )
{
cServerSocket* serverSocket = m_sockets[i];
if( serverSocket )
{
delete serverSocket;
serverSocket = NULL;
}
}
m_sockets.clear();
}
//////////////////////////////////////////////////////////////////////
// Operation
//////////////////////////////////////////////////////////////////////
BOOL cServerSocketManager::AddSocket(const uint16 port, const int32 backlog, uint32& ID)
{
cServerSocket* serverSocket = new cServerSocket;
if( serverSocket )
{
if( !serverSocket->Startup() )
{
delete serverSocket;
Information( _T("[%lu]LS system :: server socket startup(%lu)\r\n"), GetCurrentThreadId(), GetLastError() );
return FALSE;
}
if( !serverSocket->CreateSocket() )
{
delete serverSocket;
Information( _T("[%lu]LS system :: server socket create(%lu)\r\n"), GetCurrentThreadId(), GetLastError() );
return FALSE;
}
if( !serverSocket->Bind(port) )
{
delete serverSocket;
Information( _T("[%lu]LS system :: server socket bind(%lu)\r\n"), GetCurrentThreadId(), GetLastError() );
return FALSE;
}
if( !serverSocket->Listen(backlog) )
{
delete serverSocket;
Information( _T("[%lu]LS system :: server socket listen(%lu)\r\n"), GetCurrentThreadId(), GetLastError() );
return FALSE;
}
ID = m_sockets.size();
m_sockets.push_back( serverSocket );
return TRUE;
}
return FALSE;
}
cServerSocket* cServerSocketManager::GetSocket(const uint32 ID)
{
return (ID < m_sockets.size()) ? m_sockets.at(ID) : NULL;
}
@@ -0,0 +1,24 @@
#pragma once
#include <vector>
#include "cServerSocket.h"
class cServerSocketManager
{
public:
cServerSocketManager(void);
~cServerSocketManager(void);
void Init();
void Destroy();
public:
BOOL AddSocket(const uint16 port, const int32 backlog, uint32& ID);
cServerSocket* GetSocket(const uint32 ID);
const uint32 GetCount() { return m_sockets.size(); }
protected:
typedef std::vector<cServerSocket*> SERVERSOCKETS;
SERVERSOCKETS m_sockets;
};
+273
View File
@@ -0,0 +1,273 @@
#include "StdAfx.h"
#include "cSystem.h"
#include "cSocket.h"
#include "../include/cSingleton.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cSocket::cSocket(void) : m_socket(INVALID_SOCKET), m_IP(0)
{
Init();
}
cSocket::~cSocket(void)
{
Destroy();
}
void cSocket::Init()
{
m_olReceive.Alloc(cSingleton<cSystem>::GetInstance()->GetPacket());
m_olReceive.SetOperation(E_IO_RECEIVE);
m_olAccept.SetOperation(E_IO_ACCEPT);
m_olDisconnect.SetOperation(E_IO_DISCONNECT);
CreateSocket();
}
void cSocket::Destroy()
{
CloseSocket();
m_olReceive.Destroy();
}
//////////////////////////////////////////////////////////////////////
// Operation
//////////////////////////////////////////////////////////////////////
BOOL cSocket::CreateSocket()
{
CloseSocket();
m_socket = WSASocket( AF_INET,
SOCK_STREAM,
IPPROTO_TCP,
NULL,
NULL,
WSA_FLAG_OVERLAPPED);
if(m_socket == INVALID_SOCKET)
{
return FALSE;
}
BOOL sockOpt = TRUE;
if(setsockopt(m_socket,
IPPROTO_TCP,
TCP_NODELAY,
reinterpret_cast<char*>(&sockOpt),
sizeof(sockOpt)) == SOCKET_ERROR)
{
CloseSocket();
return FALSE;
}
int32 sockBuffer = 0;
if(setsockopt( m_socket,
SOL_SOCKET,
SO_SNDBUF,
reinterpret_cast<char*>(&sockBuffer),
sizeof(sockBuffer)) == SOCKET_ERROR)
{
CloseSocket();
return FALSE;
}
//LINGER lingerStruct;
//lingerStruct.l_onoff = 0;
//lingerStruct.l_linger = 0; // TIME_WAIT : 0 sec
//setsockopt(m_socket,
// SOL_SOCKET,
// SO_LINGER,
// reinterpret_cast<char*>(&lingerStruct),
// sizeof(lingerStruct));
/*
if(setsockopt( m_socket,
SOL_SOCKET,
SO_RCVBUF,
reinterpret_cast<char*>(&sockBuffer),
sizeof(sockBuffer)) == SOCKET_ERROR)
{
CloseSocket();
return FALSE;
}
*/
return TRUE;
}
void cSocket::CloseSocket()
{
if(m_socket != INVALID_SOCKET)
{
shutdown(m_socket, SD_BOTH);
closesocket(m_socket);
m_socket = INVALID_SOCKET;
}
}
void cSocket::Disconnect()
{
CleanOverlapped(E_IO_DISCONNECT);
TransmitFile( m_socket,
NULL,
0,
0,
&(m_olDisconnect.m_overlapped),
NULL,
TF_DISCONNECT | TF_REUSE_SOCKET);
}
BOOL cSocket::SendRequest(cIocpOv* sendOvl)
{
DWORD dwBytes=0, flags=0;
if(SOCKET_ERROR == WSASend(
m_socket,
&(sendOvl->m_wsaBuf),
1,
&dwBytes,
flags,
&(sendOvl->m_overlapped),
NULL))
{
DWORD error = WSAGetLastError();
if(error != WSA_IO_PENDING)
{
Debug(_T("LS system :: send error(%lu)\n"), error);
SendCompleted(sendOvl);
return FALSE;
}
}
return TRUE;
}
void cSocket::Reset()
{
GetPeerAddress();
cDoubleOV::Reset();
}
BOOL cSocket::Flush()
{
if(FALSE == cDoubleOV::IsSending())
{
// 메모리풀에서 사용할 버퍼를 꺼낸다
cIocpOv* sendOvl = cDoubleOV::Pop();
if(!sendOvl) return TRUE;
//Debug("LS system :: flush(%lu)\n", sendOvl->GetDataLength());
sendOvl->SetOperation(E_IO_SEND);
return SendRequest(sendOvl);
}
return FALSE;
}
BOOL cSocket::SendRequest(uint8* buffer, uint32 length)
{
if(FALSE == cDoubleOV::Appendable(length))
{
if(FALSE == Flush())
{
return FALSE;
}
}
if(FALSE == cDoubleOV::AppendBuffer(buffer, length))
{
Flush();
}
return TRUE;
}
BOOL cSocket::ReceiveRequest()
{
DWORD flags=0, recvBytes=0;
CleanOverlapped(E_IO_RECEIVE);
int32 iRet = WSARecv(m_socket,
static_cast<LPWSABUF>(&m_olReceive.m_wsaBuf),
1,
&recvBytes,
&flags,
(LPWSAOVERLAPPED)GetOverlapped(E_IO_RECEIVE),
NULL);
if(iRet == SOCKET_ERROR)
{
if(WSAGetLastError() != WSA_IO_PENDING)
{
Debug(_T("LS system :: receive error\n"));
return FALSE;
}
}
return TRUE;
}
void cSocket::CleanOverlapped(E_IO_OPERATION iocpOP)
{
switch(iocpOP)
{
case E_IO_RECEIVE :
m_olReceive.Clean();
break;
case E_IO_ACCEPT :
m_olAccept.Clean();
break;
case E_IO_DISCONNECT :
m_olDisconnect.Clean();
break;
}
}
LPWSAOVERLAPPED cSocket::GetOverlapped(E_IO_OPERATION iocpOP)
{
switch(iocpOP)
{
case E_IO_RECEIVE :
return &(m_olReceive.m_overlapped);
break;
case E_IO_ACCEPT :
return &(m_olAccept.m_overlapped);
break;
case E_IO_DISCONNECT :
return &(m_olDisconnect.m_overlapped);
break;
}
return NULL;
}
void cSocket::SendCompleted(cIocpOv* sendOvl)
{
sendOvl->Clean();
cDoubleOV::Push(sendOvl);
}
void cSocket::GetPeerAddress()
{
SOCKADDR_IN *localAddr, *remoteAddr;
int localLen = 0, remoteLen = 0;
GetAcceptExSockaddrs(GetWsaBuffer(),
0,
sizeof(SOCKADDR_IN) + 16,
sizeof(SOCKADDR_IN) + 16,
(LPSOCKADDR*)&localAddr,
&localLen,
(LPSOCKADDR*)&remoteAddr,
&remoteLen);
m_IP = remoteAddr->sin_addr.S_un.S_addr;
}
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include "cIocpOv.h"
#include "cDoubleOV.h"
class cSocket : public cDoubleOV
{
public:
cSocket(void);
~cSocket(void);
void Init();
void Destroy();
public:
virtual void Disconnect();
public:
BOOL CreateSocket();
void CloseSocket();
void Reset();
BOOL Flush();
BOOL SendRequest( uint8* buffer, uint32 length );
BOOL ReceiveRequest();
void SendCompleted( cIocpOv* iocpOv );
void GetPeerAddress();
public:
void CleanOverlapped( E_IO_OPERATION iocpOP );
LPWSAOVERLAPPED GetOverlapped( E_IO_OPERATION iocpOP );
SOCKET GetSockHandle() { return m_socket; }
uint8* GetWsaBuffer() { return (reinterpret_cast<uint8*>(m_olReceive.m_wsaBuf.buf)); }
protected:
BOOL SendRequest( cIocpOv* sendOvl );
protected:
SOCKET m_socket;
cIocpOv m_olReceive;
cOverlapped m_olAccept;
cOverlapped m_olDisconnect;
uint32 m_IP;
};
+31
View File
@@ -0,0 +1,31 @@
#include "StdAfx.h"
#include "cStorage.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cStorage::cStorage(void)
{
Init();
}
cStorage::~cStorage(void)
{
Destroy();
}
void cStorage::Init()
{
}
void cStorage::Destroy()
{
DestroyStorage();
}
//////////////////////////////////////////////////////////////////////
// Operation
//////////////////////////////////////////////////////////////////////
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include "cBuffer.h"
class cStorage
{
public:
cStorage(void);
~cStorage(void);
void Init();
void Destroy();
public:
BOOL CreateStorage( uint32 length ) { return m_storage.Create(length); }
void DestroyStorage() { m_storage.Destroy(); }
BOOL StoreBuffer( uint8* buffer, uint32 length ) { return m_storage.Copy( buffer, length ); }
void CleanStorage() { m_storage.Erase(); }
uint8* GetStorageBuffer() { return m_storage.GetBuffer(); }
uint32 GetStorageLength() { return m_storage.GetLength(); }
protected:
cBuffer m_storage;
};
+170
View File
@@ -0,0 +1,170 @@
// cSystem.cpp: implementation of the cSystem class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cSystem.h"
#include "../include/cSingleton.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cSystem::cSystem() : m_IOCP(NULL), m_network(NULL), m_module(NULL), m_communicator(NULL), m_packet(0), m_encoding(0), m_processor(NULL)
{
Init();
}
cSystem::~cSystem()
{
Destroy();
}
void cSystem::Init()
{
Trace( _T("cSystem::Init()\n") );
}
void cSystem::Destroy()
{
Trace( _T("cSystem::Destroy()\n") );
Cleanup();
if( m_IOCP )
{
delete m_IOCP;
m_IOCP = NULL;
}
if( m_network )
{
delete m_network;
m_network = NULL;
}
if( m_module )
{
delete m_module;
m_module = NULL;
}
if( m_communicator )
{
delete m_communicator;
m_communicator = NULL;
}
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
// startup/cleanup
BOOL cSystem::Startup( const uint32 maxSession, const uint32 maxPacket, const uint32 maxQueue, const uint32 encoding )
{
SetPool( maxQueue );
SetPacket( maxPacket );
SetEncoding( encoding );
m_IOCP = new cIOCP;
m_network = new cNetwork;
m_module = new cModule;
m_communicator = new cCommunicator(maxQueue);
if( m_IOCP->Create() && m_network->Startup(maxSession) )
{
Trace( _T("cSystem::Startup() - success.\n") );
return TRUE;
}
Information( _T("cSystem::Startup() - failed.\n") );
return FALSE;
}
void cSystem::Cleanup()
{
Trace( _T("cSystem::Cleanup()\n") );
if( m_IOCP )
{
m_IOCP->Close();
}
}
// start/end module
BOOL cSystem::StartModule( const E_THREADID threadId, const uint32 count )
{
Trace( _T("cSystem::StartModule(), ThreadID(%d), Count(%d)\n"), threadId, count );
if( m_module )
{
return m_module->StartModule( threadId, count );
}
return FALSE;
}
void cSystem::EndModule()
{
Trace( _T("cSystem::EndModule()\n") );
if( m_module )
{
m_module->EndModule();
}
}
// set configuration
void cSystem::SetProcessor( IProcessor* processor )
{
m_processor = processor;
}
void cSystem::SetEvent( const uint32 connectId, const uint32 disconnectId )
{
m_eventID[ 0 ] = connectId;
m_eventID[ 1 ] = disconnectId;
}
void cSystem::SetPool( const uint32 pool)
{
m_pool = pool;
}
void cSystem::SetPacket( const uint32 packet)
{
m_packet = packet;
}
void cSystem::SetEncoding( const uint32 encoding)
{
m_encoding = encoding;
}
BOOL cSystem::Listen( const uint16 port, const uint32 backlog )
{
if( m_network )
{
// ¼­¹ö¼ÒÄÏ »ý¼º
uint32 ID = 0;
if( m_network->CreateServerSocket( port, backlog, ID ) )
{
// nBackLog¸¸Å­ Accept¿äû
if( !m_network->AcceptReqeust( ID ) )
{
Information( _T("cSystem::Listen() failed.\r\n") );
return FALSE;
}
//Information( _T("cSystem::Listen() success.\r\n") );
return TRUE;
}
}
Information( _T("cSystem::Listen() failed - network\r\n") );
return FALSE;
}
BOOL cSystem::Connect( const uint32 ID, const TCHAR* IP, const uint16 port )
{
if( m_network )
{
Trace( _T("cSystem::UseConnector() success.\n") );
return m_network->AddConnector( ID, IP, port );
}
Information( _T("cSystem::UseConnector() failed.\n") );
return FALSE;
}
+82
View File
@@ -0,0 +1,82 @@
// cSystem.h: interface for the cSystem class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include "cIOCP.h"
#include "cNetwork.h"
#include "cModule.h"
#include "cCommunicator.h"
#include "cCommandQueue.h"
#include "../include/IProcessor.h"
class cSystem
{
public:
cSystem();
virtual ~cSystem();
void Init();
void Destroy();
public:
BOOL Startup( const uint32 maxSession, const uint32 maxPacket, const uint32 maxQueue, const uint32 encoding);
void Cleanup();
BOOL StartModule( const E_THREADID threadId, const uint32 count );
void EndModule();
void SetProcessor( IProcessor* processor );
void SetEvent( const uint32 connectId, const uint32 disconnectId );
inline void SetPool( const uint32 pool);
inline void SetPacket( const uint32 packet);
inline void SetEncoding( const uint32 encoding);
BOOL Listen( const uint16 port, const uint32 backlog );
BOOL Connect( const uint32 ID, const TCHAR* IP, const uint16 port );
public:
IProcessor* GetProcessor()
{
return ( m_processor ? m_processor : NULL );
}
cCommandQueue* GetCommandQueue()
{
return ( m_communicator ? m_communicator->GetCommandQueue() : NULL );
}
cConnectorQueue* GetConnectorQueue()
{
return ( m_communicator ? m_communicator->GetConnectorQueue() : NULL );
}
uint32 GetConnectEvent() { return m_eventID[0]; }
uint32 GetDisconnectEvent() { return m_eventID[1]; }
uint32 GetPool() { return m_pool; }
uint32 GetPacket() { return m_packet; }
uint32 GetEncoding() { return m_encoding; }
public:
cIOCP* GetIOCP() { return m_IOCP; }
cNetwork* GetNetwork() { return m_network; }
cModule* GetModule() { return m_module; }
cCommunicator* GetCommunicator() { return m_communicator; }
private:
cIOCP* m_IOCP;
cNetwork* m_network;
cModule* m_module;
cCommunicator* m_communicator;
private:
uint32 m_eventID[2];
uint32 m_pool;
uint32 m_packet;
uint32 m_encoding;
IProcessor* m_processor;
};
@@ -0,0 +1,399 @@
// cWorkerThread.cpp: implementation of the cWorkerThread class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cIocpContext.h"
#include "cPacket.h"
#include "cSystem.h"
#include "cWorkerThread.h"
#include "../include/cSingleton.h"
#ifndef CONTAINING_RECORD
#define CONTAINING_RECORD(address, type, field) \
((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
cWorkerThread::cWorkerThread() : m_packet(NULL)
{
Init();
}
cWorkerThread::~cWorkerThread()
{
Destroy();
}
void cWorkerThread::Init()
{
uint32 maxPacket = cSingleton<cSystem>::GetInstance()->GetPacket();
uint32 encoding = cSingleton<cSystem>::GetInstance()->GetEncoding();
m_packet = new cPacket( encoding );
m_storage.Create( maxPacket * 4 );
}
void cWorkerThread::Destroy()
{
if(m_packet)
{
delete m_packet;
m_packet = NULL;
}
}
//////////////////////////////////////////////////////////////////////
// operation
//////////////////////////////////////////////////////////////////////
void cWorkerThread::Process()
{
BOOL success;
DWORD bytesTransferred;
cSystem* system = cSingleton<cSystem>::GetInstance();
cOverlapped* iocpOv = NULL;
cIocpContext* iocpContext = NULL;
LPWSAOVERLAPPED lpOverlapped = NULL;
cIOCP* IOCP = system->GetIOCP();
cNetwork* network = system->GetNetwork();
Trace( _T("WorkerThread :: %lu\r\n"), GetCurrentThreadId() );
while( !IsTerminated() )
{
iocpContext = NULL;
lpOverlapped = NULL;
success = IOCP->GetIocpStatus( &bytesTransferred,
reinterpret_cast<PULONG>(&iocpContext),
&lpOverlapped );
if( !lpOverlapped )
{
Trace( _T("GQCS timeout\r\n") );
continue;
}
// 이벤트 검사
iocpOv = reinterpret_cast<cOverlapped*>(lpOverlapped);
switch( iocpOv->GetOperation() )
{
case E_IO_ACCEPT : // 여기서 iocpContext는 cServerSocket객체임
{
iocpContext = CONTAINING_RECORD( lpOverlapped, cIocpContext, m_olAccept );
// Accept 요청완료
network->AcceptCompleted( iocpContext->GetPortID() );
if( !success )
{
// 접속 대기 중 오류 - backlog된 소켓이 종료됐을때
Debug( _T("WorkerThread :: E_IO_ACCEPT failed\r\n") );
network->Finish( iocpContext );
continue;
}
if( !iocpContext->IsAssociated() )
{
// 미등록된 Context를 IOCP에 등록
if( !IOCP->AssocInstance( reinterpret_cast<HANDLE>(iocpContext->GetSockHandle()),
reinterpret_cast<DWORD>(iocpContext) ) )
{
// 접속 대기 중 오류 - 이미 등록되어 있거나 기타 오류시
Debug( _T("WorkerThread :: AssocInstance failed\r\n") );
network->Finish( iocpContext );
continue;
}
iocpContext->Associate();
}
// 접속성공
iocpContext->Reset();
// Receive 요청
if( !iocpContext->ReceiveRequest() )
{
iocpContext->Disconnect();
}
OnConnect( iocpContext );
// 새로운 Accept 요청
network->AcceptReqeust( iocpContext->GetPortID() );
}
break;
case E_IO_RECEIVE :
{
if( !success || !bytesTransferred )
{
OnDisconnect( iocpContext );
continue;
}
// 패킷 처리
if( OnReceive( iocpContext, bytesTransferred ) )
{
// Receive 요청
if( !iocpContext->ReceiveRequest() )
{
OnDisconnect( iocpContext );
}
}
}
break;
case E_IO_SEND :
{
cIocpOv* sendOvl = reinterpret_cast<cIocpOv*>(lpOverlapped);
if( iocpContext )
{
// 전송버퍼 push
iocpContext->SendCompleted( sendOvl );
//Debug( _T("WorkerThread :: Sent(%lu)\r\n"), bytesTransferred );
}
if( !success )
{
Debug( _T("WorkerThread :: E_IO_SEND failed\r\n") );
}
}
break;
case E_IO_DISCONNECT :
{
if( success && iocpContext )
{
// Context를 반환하고 새로운 접속을 요청
network->Finish( iocpContext );
}
else
{
Debug( _T("WorkerThread :: E_IO_DISCONNECT failed\r\n") );
}
}
break;
default :
{
Debug( _T("WorkerThread :: Bad operation\r\n") );
}
break;
}
}
}
BOOL cWorkerThread::OnConnect( cIocpContext* iocpContext )
{
if( iocpContext->IsActive() )
{
PushCommand( EVENT_CONNECT, iocpContext );
return TRUE;
}
return FALSE;
}
BOOL cWorkerThread::OnDisconnect( cIocpContext* iocpContext )
{
if( iocpContext->IsActive() )
{
PushCommand( EVENT_CLOSE, iocpContext );
return TRUE;
}
return FALSE;
}
BOOL cWorkerThread::OnReceive( cIocpContext* iocpContext, DWORD length )
{
if( iocpContext->IsActive() )
{
//Trace( _T("[%lu]OnReceive : %lu\r\n"), GetCurrentThreadId(), length );
// 임시버퍼에 보관된 데이타와 현재받은 데이타를 복사한다
if( iocpContext->GetStorageLength() > 0 )
{
m_storage.Erase();
if( !m_storage.Copy( iocpContext->GetStorageBuffer(), iocpContext->GetStorageLength() ) )
{
OnDisconnect( iocpContext );
return FALSE;
}
if( !m_storage.Append( iocpContext->GetWsaBuffer(), length ) )
{
OnDisconnect( iocpContext );
return FALSE;
}
}
else
{
m_storage.Erase();
if( !m_storage.Copy( iocpContext->GetWsaBuffer(), length ) )
{
OnDisconnect( iocpContext );
return FALSE;
}
}
// 저장된 버퍼를 초기화
iocpContext->CleanStorage();
// 임시버퍼에 저장된 패킷을 검사하고 프로토콜 별로 나누어서 command queue에 push
return CheckPacket( iocpContext,
m_storage.GetBuffer(),
m_storage.GetLength() );
}
return FALSE;
}
BOOL cWorkerThread::CheckPacket( cIocpContext* iocpContext, uint8* buffer, uint32 length )
{
//Trace( _T("[%lu]CheckPacket : %lu\r\n"), GetCurrentThreadId(), length );
// 패킷의 헤더길이 검사
if( length < sizeof(cHeader) )
{
// 헤더보다 작은 패킷이 들어왔을 경우 저장하고 끝난다
iocpContext->StoreBuffer( buffer, length );
//Trace( _T("[%lu]very short header : %lu, total : %lu\r\n"), GetCurrentThreadId(), length, iocpContext->GetBufferLength() );
return TRUE;
}
// 헤더로 페이로드 길이 확인
cHeader* header = reinterpret_cast<cHeader*>(buffer);
Trace(_T("header : %lu, context : %lu\r\n"), header->GetSequence(), iocpContext->GetSequence());
if( !header->IsPerfect(iocpContext->GetSequence()) )
{
// 잘못된 헤더가 들어왔을때 패킷을 drop한다
OnDisconnect( iocpContext );
Debug( _T("[%lu]invalid packet : %lu\r\n"), GetCurrentThreadId() );
return FALSE;
}
if( header->GetPayload() > (m_storage.GetMaxLength()-m_storage.GetLength()) )
{
Debug( _T("[%lu]too large payload : %lu\r\n"), GetCurrentThreadId(), header->GetPayload() );
OnDisconnect( iocpContext );
return FALSE;
}
// 패킷 헤더에 따른 길이 검사
uint32 packetLength = sizeof(cHeader) + header->GetPayload();
if( length < packetLength ) // 패킷길이가 잘려서 들어왔다
{
//Trace( _T("[%lu]short than payload : %lu\r\n"), GetCurrentThreadId(), packetLength );
iocpContext->StoreBuffer( buffer, length );
Trace( _T("[%lu]very short payload : %lu, store : %lu, total : %lu\r\n"), GetCurrentThreadId(), header->GetPayload(), length, iocpContext->GetStorageLength() );
}
else if( length == packetLength ) // 패킷길이가 정확하게 들어왔다
{
Trace( _T("[%lu]good payload : %lu\r\n"), GetCurrentThreadId(), header->GetPayload() );
// decryption 후 command queue에 push
if( !PushCommand( EVENT_RECEIVE,
iocpContext,
buffer,
packetLength ) )
{
OnDisconnect( iocpContext );
return FALSE;
}
}
else if( length > packetLength ) // 패킷길이가 붙어서 들어왔다
{
Trace( _T("[%lu]too large payload : %lu\r\n"), GetCurrentThreadId(), header->GetPayload() );
// decryption 후 command queue에 push
if( !PushCommand( EVENT_RECEIVE,
iocpContext,
buffer,
packetLength ) )
{
OnDisconnect( iocpContext );
return FALSE;
}
// 다시 한번 패킷 검사
return CheckPacket( iocpContext, buffer+packetLength, length-packetLength );
}
return TRUE;
}
BOOL cWorkerThread::PushCommand( EventID eventId, cIocpContext* iocpContext, uint8* buffer, uint32 length )
{
cSystem* system = cSingleton<cSystem>::GetInstance();
cCommandQueue* commandQueue = system->GetCommandQueue();
if( !commandQueue ) return TRUE;
switch( eventId )
{
case EVENT_CONNECT :
{
commandQueue->PushCommand( iocpContext, system->GetConnectEvent() );
}
break;
case EVENT_CLOSE :
{
commandQueue->PushCommand( iocpContext, system->GetDisconnectEvent() );
}
break;
case EVENT_RECEIVE :
{
if( length == 0 )
{
// 디코딩 실패
OnDisconnect( iocpContext );
return FALSE;
}
// 시퀀스 추가
iocpContext->PopSequence();
//// 패킷의 유효성 검사
cHeader* header = reinterpret_cast<cHeader*>(buffer);
//if( !header->IsPerfect(iocpContext->GetSequence()) )
//{
// OnDisconnect( iocpContext );
// return FALSE;
//}
uint8* packet = buffer + sizeof(cHeader);
uint32 payload = length - sizeof(cHeader);
// 패킷 디코딩
uint32 result = 0;
if(TRUE == m_packet->Decode(
packet,
length - sizeof(cHeader),
header->GetSequence(),
result))
{
commandQueue->PushCommand(
iocpContext,
header->GetCommand(),
m_packet->GetOutput(),
result );
}
else
{
commandQueue->PushCommand(
iocpContext,
header->GetCommand(),
packet,
static_cast<uint16>(payload) );
}
}
break;
}
return TRUE;
}
@@ -0,0 +1,44 @@
#pragma once
#include "cBaseThread.h"
#include "cBuffer.h"
#include "cPacket.h"
class cIocpContext;
enum EventID
{
EVENT_CONNECT = 1,
EVENT_RECEIVE,
EVENT_CLOSE
};
//////////////////////////////////////////////////////////////////////
// IOCP Worker Thread
//////////////////////////////////////////////////////////////////////
class cWorkerThread : public cBaseThread
{
public:
cWorkerThread();
virtual ~cWorkerThread();
void Init();
void Destroy();
public:
BOOL OnConnect( cIocpContext* iocpContext );
BOOL OnDisconnect( cIocpContext* iocpContext );
BOOL OnReceive( cIocpContext* iocpContext, DWORD length );
BOOL CheckPacket( cIocpContext* iocpContext, uint8* buffer, uint32 length );
BOOL PushCommand( EventID eventId, cIocpContext* iocpContext, uint8* buffer = NULL, uint32 length = 0);
protected:
virtual void Process();
protected:
cBuffer m_storage;
cPacket *m_packet;
};
+14
View File
@@ -0,0 +1,14 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ApolloL.rc
// 다음은 새 개체에 사용할 기본값입니다.
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif