[Network] 5. FlatBuffers + Boost Asio 콘솔 서버 예제 (1)
Server 구조
자 그럼 서버 코드를 작성해보도록 하겠습니다. 서버 코드 클래스의 구조는 위와 같습니다.
서버의 구조는 Boost Asio 로 구성되며 윈도우 플랫폼에서는 내부적으로 Proactor 패턴의 IOCP로 작동됩니다.
각 클래스의 구조는 서버 클래스인 CServer와 각각의 세션 Entity 인 CSession, 그리고 접속하여 채팅하는 공간이 필요하므로 채팅방 클래스인 CChatRoom, 마지막으로 패킷데이터 관리를 위한 CMessage 클래스까지 4개의 클래스로 작성됩니다. 여기에 마지막으로 FlatBuffers 라이브러리가 사용되어 패킷 직렬화를 아주 쉽고 간단하게 도와줄 겁니다.
이 서버는 CServer에서 접속자를 기다리며 접속자가 접속 요청이 오면 Accep 하여 세션을 할당하고 할당된 세션의 유저 정보를 받은 다음 채팅방으로 접속하여 채팅방에서 메시지를 주고 받는 구조로 설계됩니다.
CMessage 클래스
자 그럼 공통적으로 서버와 클라이언트에서 사용되는 CMessage 클래스부터 작성하도록 하겠습니다. 통상적으로 FlatBuffers에서 사용하는 데이터 타입의 경우 uint_8_t * 타입이므로 해당 타입으로 작성되었습니다.
구조는 헤더 부분과 바디부분으로 나뉘어 헤더 부분에는 바디의 길이정보를 바디는 데이터를 담습니다.
Message.cpp
#pragma once
class CMessage
{
public:
enum { header_length = 4 };
enum { max_body_length = 512 };
public:
CMessage() {}
CMessage(const uint8_t* body, size_t body_size)
: m_Body_length(body_size)
{
assert(body_size <= max_body_length);
std::copy(body, body + body_size, this->body());
encode_header();
}
public:
const uint8_t* data() const
{
return m_pData;
}
uint8_t* data()
{
return m_pData;
}
std::size_t length() const
{
return header_length + m_Body_length;
}
const uint8_t* body() const
{
return m_pData + header_length;
}
uint8_t* body()
{
return m_pData + header_length;
}
std::size_t body_length() const
{
return m_Body_length;
}
void body_size(std::size_t new_size)
{
assert(new_size <= max_body_length);
m_Body_length = new_size;
}
bool decode_header()
{
char header[header_length + 1] = { 0, };
strncat_s(header, (char*)m_pData, header_length);
m_Body_length = std::atoi(header);
if (m_Body_length > max_body_length)
{
m_Body_length = 0;
return false;
}
return true;
}
void encode_header()
{
char header[header_length + 1] = { 0, };
sprintf_s(header, "%4d", static_cast<int>(m_Body_length));
memcpy(m_pData, header, header_length);
}
private:
uint8_t m_pData[header_length + max_body_length] = { 0, };
std::size_t m_Body_length = 0;
};
기본 베이스는 boost asio 예제코드의 message.cpp에서 가져온 것이고 조금 변경하여 다듬었습니다.
별로 어려운 것은 없으며 데이터를 담고 헤더에는 데이터 길이를 담습니다.
헤더의 길이 정보를 담는 코드는 encode_header(), decode_header()가 담당하게 됩니다.
'프로그래밍 언어 > Flatbuffers' 카테고리의 다른 글
[Network] 7. FlatBuffers + Boost Asio 콘솔 서버 예제 (3) (0) | 2021.07.07 |
---|---|
[Network] 6. FlatBuffers + Boost Asio 콘솔 서버 예제 (2) (0) | 2021.07.05 |
[Network] 4. Flatbuffers + Boost Asio 콘솔 채팅 서버 클라이언트 예제 (0) | 2021.07.03 |
[Network] 3. FlatBuffers 사용 예제 코드 (0) | 2021.05.28 |
[Network] 2. FlatBuffers 사용하기 (2) | 2021.05.28 |