본문 바로가기

[단계별로 IOCP 실습] 3단계 애플리케이션과 네트워크 코드 분리

@iamrain2025. 8. 4. 16:23
  • IOCP를 네트워크 라이브러리로 분리
  • 연결, 끊어짐, 데이터 수신 이벤트를 애플리케이션에 전달하는 구조 구현
  • 모듈화 및 재사용성 향상

네트워크 라이브러리로 분리

`IOCompletionPort.h`를 `IOCPServer.h`로 이름을 변경하고 `Define.h`와 함께 `ServerNetwork` 필터로 이동.

연결, 끊어짐, 데이터 수신 이벤트를 애플리케이션에 전달하는 구조 구현

`IOCPServer` 클래스에서 `EchoServer` 클래스로 정보를 전달하고 콘솔(애플리케이션)에서 해당 내용을 띄워주도록 구현.

 

부모 클래스에 선언하면 자식 클래스가 반드시 상속받아서 사용해야 하는 `virtual` 함수를 사용.

virtual void OnConnect(const UNIT32 clientIndex) {}
virtual void OnClose(const UNIT32 clientIndex) {}
virtual void OnReceive(const UNIT32 clientIndex, const UINT32 dataSize, char* data) {}
  • `OnConnect()`
    클라이언트가 연결 되었을 때 호출되는 함수
  • `OnClose()`
    클라이언트가 연결 종료되었을 때 호출되는 함수
  • `OnReceive()`
    클라이언트가 데이터를 수신했을 때 호출되는 함수

가상함수의 인자로 필요한 정보를 받고 데이터를 상속받은 클래스에서 사용.

`IOCPServer` 클래스 내부 함수에 가상함수가 호출될 부분에서 사용.

class IOCPServer
{
public:
	IOCPServer(void) {}

	virtual ~IOCPServer(void)
	{
		WSACleanup();
	}
    
    ...
    
	virtual void OnConnect(const UINT32 clientIndex) {}
	virtual void OnClose(const UINT32 clientIndex) {}
	virtual void OnReceive(const UINT32 clientIndex, const UINT32 dataSize, char* data) {}

private:
	...

	void WokerThread()
	{
		...

		while (mIsWorkerRun)
		{
			...

			if (IOOperation::RECV == pOverlappedEx->m_eOperation)
			{
				OnReceive(pClientInfo->mIndex, dwIoSize, pClientInfo->mRecvBuf);

				...
			}
			...
		}
	}

	void AccepterThread()
	{
		...

		while (mIsAccepterRun)
		{
			...

			OnConnect(pClientInfo->mIndex);

			...
		}
	}

	void CloseSocket(stClientInfo* pClientInfo, bool bIsForce = false)
	{
		...

		OnClose(clientIndex);
	}

 

`EchoServer` 클래스 작성

#pragma once

#include "IOCPServer.h"

class EchoServer : public IOCPServer
{
	virtual void OnConnect(const UINT32 clientIndex) override
	{
		printf("[OnConnect] Client Connected : Index(%d) \n", clientIndex);
	}

	virtual void OnClose(const UINT32 clientIndex) override
	{
		printf("[OnClose] Client Closed : Index(%d) \n", clientIndex);
	}

	virtual void OnReceive(const UINT32 clientIndex, const UINT32 dataSize, char* data) override
	{
		printf("[OnReceive] Client : Index(%d), Data Reception %d bytes, Received Data : %s \n", clientIndex, dataSize, data);
	}
};


테스트 클라이언트에서 Echo 메시지를 보내면 메시지가 출력되지 않음.
패킷 규격의 차이로 인해 메시지 버퍼에서 메시지가 시작되는 주소가 달라서 생기는 현상.

 

5번째 주소 값부터 전송하도록 수정.

OnReceive(pClientInfo->m_socketClient, dwIoSize, (pClientInfo->m_recvBuf + 5));

 

iamrain
@iamrain :: Annals of Unreal

iamrain 님의 블로그 입니다.

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차