Server/C++

Google Protobuf - 2) 패킷 송수신

Juzdalua 2024. 8. 21. 00:29

- 다양한 방법으로 데이터를 지원해준다.

- 현업에서 대중적으로 사용한다고 한다. -> 협업시 프로토콜을 맞추기에 용이하다.

- 임시객체를 꼭 임시로만 사용할 필요는 없다.

- C++, C# 지원이 가능해서 Unity와 연동도 가능하다.

 

xml, JSON 보다 사용도가 더 높은 Protocol buffer라고 한다.

// PDL.xml

<?xml version="1.0" encoding="utf-8"?>
<PDL>
	<Packet name="S_TEST" desc="테스트">
		<Field name="id" type="uint64" desc=""/>
		<Field name="hp" type="uint32" desc=""/>
		<Field name="attack" type="uint16" desc=""/>
		<List name="buffs" desc="">
			<Field name="buffId" type="uint64" desc=""/>
			<Field name="remainTime" type="float" desc=""/>
			<List name="victims">
				<Field name="userId" type="uint64"/>
			</List>
		</List>
	</Packet>
</PDL>

// Protocol.proto

syntax = "proto3"; // version
package Protocol; // namespace

message BuffData
{
	uint64 buffId = 1;
	float remainTime = 2;
	repeated uint64 victims = 3;
}

message S_TEST
{
	uint64 id = 1; // = 1 -> 첫 번째 위치. 초기값 아님
	uint32 hp = 2;
	uint32 attack = 3;
	repeated BuffData buffs = 4; // repeated -> 가변데이터
}

 

Server

#include <iostream>
#include "Protocol.pb.h"

int main()
{
    while (true)
    {
        // Protocol.proto의 package Protocao -> Protocol:: 사용
        Protocol::S_TEST pkt;
        pkt.set_id(1000);
        pkt.set_hp(100);
        pkt.set_attack(10);

        {
            // 구조체 형태의 repeated BuffData는 포인터를 반환한다.
            Protocol::BuffData* data = pkt.add_buffs();
            data->set_buffid(100);
            data->set_remaintime(1.2f);
            data->add_victims(4000); // 기본 변수 repeated는 반환 타입이 없다.
        }
        {
            Protocol::BuffData* data = pkt.add_buffs();
            data->set_buffid(200);
            data->set_remaintime(2.5f);
            data->add_victims(1000);
            data->add_victims(2000);
        }

        // 이터레이터 타입의 데이터 활용
        auto m = pkt.mutable_buffs();
        m->Add();


        SendBufferRef sendBuffer = ServerPacketHandler::MakeSendBuffer(pkt);

        GSessionManager.Broadcast(sendBuffer);
    }

    
}

 


Client

#include "Protocol.pb.h"

void ClientPacketHandler::Handle_S_TEST(BYTE* buffer, int32 len)
{
	Protocol::S_TEST pkt;

	ASSERT_CRASH(pkt.ParseFromArray(buffer + sizeof(PacketHeader), len - sizeof(PacketHeader)));

	cout << pkt.id() << ", " << pkt.hp() << ", " << pkt.attack() << endl;
	cout << "BUFSIZE: " << pkt.buffs_size() << endl;

	for (auto& buf : pkt.buffs())
	{
		cout << "BUFINFO: " << buf.buffid() << ", " << buf.remaintime() << endl;
		cout << "VICTIMS: " << buf.victims_size() << endl;
		for (auto& vic : buf.victims())
		{
			cout << vic << " ";
		}
		cout << endl;
	}
}