서버와 클라이언트는 무엇인가?
·
Camp/Standard
먼저 각 단어의 의미부터 생각해 보자.밥집으로 비유하면 좋을 것 같다. 홀을 도는 사람은 서빙을 한다.손님을 주문을 한다.홀은 손님에게 주문을 하지 않는다.손님은 홀에게 밥을 만들어 주지 않는다. 이렇게 서버와 클라이언트의 기본적인 구조는 정의가 된 것이다.서버는 클라이언트의 주문을 받고 만들어서 주기만 한다.클라이언트는 서버에게 주문을 하고 받기만 한다.  1. 서버와 클라이언트서버서버란 네트워크 상에서 다른 컴퓨터(클라이언트)에게 서비스를 제공하는 컴퓨터 또는,그 컴퓨터에서 동작하는 프로그램을 말한다.클라이언트의 요청을 받으면 그에 맞는 응답을 제공하는 역할을 하게 된다. 주문을 받으면 주방에서 조리가 이루어진다.클라이언트의 주문이 들어오면 주방에서 뭔갈 만들어서 클라이언트에게 넘여주게 되니 주방은 ..
[C++] JobTimer
·
Study/C++ & C#
이거에 대해 얘기하기 전에 스마트 포인터 사이클 이슈를 해결해 보자. 1. 사이클 문제 아래와 같이 클라이언트가 종료돼도 GameSession의 소멸자가 호출되지 않는 메모리 릭 현상이 발생한다. 지금은 문제라고 부르기도 뭐한 수준이지만, 만약 이런 현상이 계속 라이브에서 발생한다고 생각해 보자. 예상치 못한 메모리 릭으로 인해 서버가 제 기능을 하지 못하게 되는 현상이 생기지 않을까? 사실 우리는 이미 사이클 문제를 인지하고 있었다. #pragma once class Player { public: uint64playerId = 0; stringname; Protocol::PlayerTypetype = Protocol::PLAYER_TYPE_NONE; GameSessionRefownerSession; /..
[C++/C#] C# 채팅 클라이언트 간보기
·
Study/C++ & C#
왜 간보기냐면 C#으로 모델을 구현하고 패킷 핸들링을 진행하지 않기 때문. 입력을 받고 출력하기만 하는 창구 역할만 수행한다. 1. 구현 방법 이미 이전에 파이썬을 활용해 패킷 자동화까지 해 놓았다. 아무래도 C#에서까지 같은 작업을 하기보단 있는 걸 끌어오는 게 편할 것 같았다. 그래서 기존의 DummyClient를 DLL로 만들어서 P/Invoke를 활용하기로 했다. 따라서 아래의 기능들이 필요하게 된다. 접속부터 패킷 핸들링 까지 할 메인 스레드 상호 간 데이터를 전달하기 위한 송수신 데이터용 Queue 데이터를 주고받기 위한 C++ 함수들 클라이언트에서 출력과 입력을 받을 각각의 스레드 2. 메인 스레드 거창할 건 없고 그냥 기존 코드의 재활용이다. extern "C" { __declspec(dl..
[C++] Packet Handler
·
Study/C++ & C#
클라이언트와 서버는 많은 종류의 패킷으로 통신하게 될 것이다. 각 패킷 ID(OPCODE) 별로 일일이 분기시키고, 반복된 코드를 계속 작성하게 된다면 매우 비효율적일 것이다. 패킷을 보다 효율적으로 관리할 수 있게 해 줄 핸들러 클래스를 작성한다. 1. 클래스 작성 서버 클라 양쪽에 핸들러를 만들어 둘 것이다. 1-1. Client #pragma once enum { S_TEST = 1 }; class ClientPacketHandler { public: static void HandlePacket(BYTE* buffer, int32 len); static void Handle_S_TEST(BYTE* buffer, int32 len); }; ID 열거형의 네임 컨벤션은 아래와 같다. S_TEST - (..
[C++] Buffer Helpers
·
Study/C++ & C#
2023.07.08 수정 rValue Ref와 Universal Ref가 혼동된 부분 수정. 패킷 직렬화 공부 과정의 첫 삽을 뜨게 됐다. Protobuf를 사용하면 어느 정도는 그냥 넘어갈 수도 있겠으나, 동작 원리와 그 장단점에 대해 아는 것이 중요하다는 그 말이 가슴에 남는다. 결국 알아야 더 잘 사용할 수 있는 게 아닐까. 1. 본격적으로 들어가기 전에 기존에 구현한 버퍼를 사용하는 방법에 대해 돌아보자. SendBufferRef sendBuffer = GSendBufferManager->Open(4096); BYTE* buffer = sendBuffer->Buffer(); ((PacketHeader*)buffer)->size = (sizeof(sendData) + sizeof(PacketHead..
[C++] SendBuffer Pooling
·
Study/C++ & C#
이전엔 단순히 버퍼를 필요할 때 만들어 사용하는 형태였다면, 이번엔 풀링을 통해 미리 버퍼들을 풀링해 돌려쓰는 방식으로 돌아가게 할 것이다. 1. SendBuffer 클래스 수정 풀링을 사용할 것이기 때문에 아래의 클래스들을 새로 작성할 것이다. SendBufferChunk - SendBuffer들의 덩어리(Chunk)이다. 버퍼들을 Array형태로 갖고 있을 것이다. SendBufferManager - SendBufferChunk들을 관리할 매니저 클래스이다. 먼저 SendBufferManager부터 만들어가 보자. class SendBufferManager { public: // 큰 버퍼에서 내가 일정 부분만큼 사용하기 위해 연다는 느낌 SendBufferRefOpen(uint32 size); pri..
[C++] RecvBuffer
·
Study/C++ & C#
지금까지 수신버퍼를 임시로 단순 배열로 만들어 사용했었다. 하지만 정말 임시적인 방편이고 제대로 된 처리를 위해 버퍼 클래스를 만들 것이다. 송신버퍼는 내용이 많으므로 별도의 글로 정리할 것이다. 1. 버퍼 클래스 작성 일단 기존 세션 헤더에 있던 버퍼 관련 내용은 다 날리고 아래와 같이 수신버퍼를 선언한다. // Session.h //... private: weak_ptr_service; SOCKET_socket = INVALID_SOCKET; NetAddress_netAddress = {}; Atomic_connected = false; private: USE_LOCK; /* 수신 관련 */ RecvBuffer_recvBuffer; /* 송신 관련 */ private: /* IocpEvent 재사용 ..
[C++] Service
·
Study/C++ & C#
오늘도 최대한 메모해 보자. 1. Service란? 여기서 서비스란 흩어져 있는 여러 기능들을 한 곳에 모아둬, 보다 편하게 사용할 수 있게 한 집합이다. 언제 리스너/송신/수신 오브젝트를 일일이 만들고 설정한단 말인가? 이전에 했던 일련의 작업들이 서비스에 포함된 상태로 동작할 것이다. 라이브 서비스에선 모든 기능을 하나의 서버에 두는 것이 아니라, 목적에 맞게 서버를 분산해 운용한다. 서버끼리 붙어야 할 일도 생길 수 있기 때문에 이에 대응해야 한다. 세션이 서버일 수도 있고 클라이언트일 수도 있기 때문에, Service라는 클래스를 두어 정책을 구분해 운용하기로 한 것이다. 1. 문제 해결 부터 본격적으로 Service에 대한 구현에 들어가기 전에 이전 과정의 문제에 대한 수정이 필요하다. 우린 C..
[C++] IOCP Core
·
Study/C++ & C#
여기서부턴 좀 더 제대로 흐름을 이해할 필요가 있는 것 같다. 아마 앞으로를 위해서도 중요할 것이다. 그런데 어떻게 정리해야 깔끔할지도 모르겠다. 그만큼 난이도가 올라간 것 같다. 1. 클래스 작성 일단 다시 Completion Port의 동작 과정에 대해 살펴보자. CP 핸들을 만든다 CP 핸들에 소켓을 등록한다 IO 함수를 건다 GetQueuedCompletionStatus()가 감지 일을 처리하고 다시 IO 함수를 건다 였다. CreateIoCompletionPort() 함수가 2가지 일을 한방에 처리하는 것은 정말 인상적이었다. 이제 이걸 하나의 작은 라이브러리의 형태로 구현해 보자. 1-1. IocpCore 이번 메모의 주제에 맞는 핵심 클래스이다. // IocpCore.h class IocpO..