flatbuffers03

flatbuffersÀÇ unionÀ» ÀÌ¿ëÇØ ³×Æ®¿÷À¸·Î ÆÐŶÀ» º¸³»´Â °£´ÜÇÑ ¿¹Á¦¸¦ ¸¸µé¾î º¸ÀÚ.
ÀÌ ¿¹Á¦´Â flatbuffers·Î ³×Æ®¿÷À¸·Î ¼Û½Å, ¼ö½Å °¡´É¼ºÀ» È®ÀÎÇϱâ À§ÇÑ ¼Ò½ºÀÌ´Ù.
ÇÁ·ÎÁ§Æ®¿¡¼­ ±×´ë·Î »ç¿ë Çϱ⿡´Â ¸¹ÀÌ ºÎÁ·ÇÑ Á¡ÀÌ ÀÖ´Ù.

³×Æ®¿÷ ÄÚµå´Â ¾Æ·¡ ½ÎÀÌÆ®¿¡¼­ ´Ù¿î·Îµå ¹Þ¾Æ Á¶±Ý ¼öÁ¤ ÇÏ¿´´Ù.
https://his130.tistory.com/378

¼öÁ¤ÇÑ ³×Æ®¿÷ ÄÚµå: networkTest.zip


unionÀ» ÀÌ¿ëÇÏ´Â ¹æ¹ýÀº ¾ÕÀå¿¡¼­ ¹è¿ü´Ù.
flatbuffers02 unionÀ» ÀÌ¿ëÇÑ Å¸ÀÔ ±¸ºÐ

IDL ÀÛ¼º

event.fbs ÆÄÀÏ
namespace MyEvent; 

table EventStart

  id : int; 
  time : float;


table EventEnd 

  id : int;
  message : string;


union EventCmd { EventStart, EventEnd } 

table EventHolder

  event : EventCmd; 


root_type EventHolder; 

¼­¹ö, Ŭ¶óÀ̾ðÆ® °øÅë Çì´õ

Ŭ¶óÀ̾ðÆ®¿Í ¼­¹ö¿¡ °øÅëÀ¸·Î »ç¿ëÇÏ´Â Çì´õÀÌ´Ù.
PACKET_SAMPLE3 ¼±¾ð ÁÖ¼®À» ÇØÁ¦Çϸé flatbuffers¸¦ ÀÌ¿ëÇØ ¼Û¼ö½ÅÀ» Å×½ºÆ® ÇÑ´Ù.

common.h
#ifndef _CCOMMON_H
#define _CCOMMON_H

//¾Æ·¡ 3°¡Áö Áß¿¡ ÇÑ°³¸¸ ÁÖ¼®À» ÇØÁ¦ ÇØ¾ß ÇÑ´Ù.

//#define PACKET_SAMPLE1  1   //¹®ÀÚ¿­ º¸³»±â
//#define PACKET_SAMPLE2  1   //±¸Á¶Ã¼ º¸³»±â
#define PACKET_SAMPLE3  1   //flatbuffers º¸³»±â

#endif // !_CCOMMON_H


    //send()ÇÔ¼ö¸¦ ÅëÇؼ­ Ŭ¶óÀ̾ðÆ®¿¡ ¸Þ¼¼Áö Àü¼Û
#ifdef    PACKET_SAMPLE1
    char message[] = "hello ! Welcome Sample1!";
    send(CliSock, message, sizeof(message), 0);
#endif

#ifdef PACKET_SAMPLE2
    SC_HELLO packet;
    send(CliSock, (char*)&packet, packet.size, 0);
#endif

#ifdef PACKET_SAMPLE3
    Send_UnionSample_Satart(CliSock, 100, 0.8f);
    Send_UnionSample_End(CliSock, 5, "quit5");
#endif


server.cpp¿¡¼­ ¼Û½Å

¼­¹ö¿¡¼­ Ŭ¶óÀ̾ðÆ® Àü¼ÛÇÒ¶§ FinishSizePrefixed ÇÔ¼ö¸¦ ÀÌ¿ëÇØ ¾Õ¿¡ 4byte¿¡ ¹öÆÛÀÇ ±æÀ̸¦ ÀúÀåÇÑ´Ù.
¾ÕÀÇ 4byte¿¡ ÀúÀåµÇ´Â Å©±â´Â bufSizeº¸´Ù 4 ÀûÀ» °ÍÀÌ´Ù.

¼­¹ö¿¡¼­´Â µÎ°³ÀÇ ÆÐŶÀ» º¸³½´Ù.
#ifdef PACKET_SAMPLE3
    Send_UnionSample_Satart(CliSock, 100, 0.8f);
    Send_UnionSample_End(CliSock, 5, "quit5");
#endif

µÎ°³ÀÇ ÆÐŶ Äڵ带 º°µµÀÇ ÇÔ¼ö·Î ÀÛ¼º ÇÏ¿´´Ù.
void Send_UnionSample_Satart(SOCKET socket, int id, float startTime)
{
    flatbuffers::FlatBufferBuilder builder;

    //Á÷·ÄÈ­ serialize
    auto startOffset = MyEvent::CreateEventStart(builder, id, startTime);
    auto rootOffset = MyEvent::CreateEventHolder(builder, MyEvent::EventCmd_EventStart, startOffset.Union());

    builder.FinishSizePrefixed(rootOffset);

    auto data = builder.GetBufferPointer();
    auto bufSize = builder.GetSize();

    flatbuffers::Verifier verifier(data, bufSize);
    bool ok = MyEvent::VerifySizePrefixedEventHolderBuffer(verifier);
    if (ok)
    {
        send(socket, (const char*)data, bufSize, 0);
    }
}

void Send_UnionSample_End(SOCKET socket, int id, std::string msg)
{
    flatbuffers::FlatBufferBuilder builder;

    //Á÷·ÄÈ­ serialize
    auto offset = MyEvent::CreateEventEnd(builder, id, builder.CreateString(msg.c_str()));
    auto rootOffset = MyEvent::CreateEventHolder(builder, MyEvent::EventCmd_EventEnd, offset.Union());

    builder.FinishSizePrefixed(rootOffset);

    auto data = builder.GetBufferPointer();
    auto bufSize = builder.GetSize();

    flatbuffers::Verifier verifier(data, bufSize);
    bool ok = MyEvent::VerifySizePrefixedEventHolderBuffer(verifier);
    if (ok)
    {
        send(socket, (const char*)data, bufSize, 0);
    }
}


Ŭ¶óÀ̾ðÆ®¿¡¼­ ¼ö½Å

flattbuffers µ¥ÀÌÅ͸¦ ¹ÞÀ»¶§´Â 4byte·Î ¹öÆÛÀÇ ±æÀ̸¦ Àаí, ¹öÆÛ Å©±â ¸¸Å­ µ¥ÀÌÅ͸¦ ¹Þ´Â´Ù.
µ¥ÀÌÅ͸¦ ¹Þ¾Æ¼­ ¿ªÁ÷·ÄÈ­ ÇÑ´Ù.

µÎ°³ÀÇ ÆÐŶÀ» ¹Þ´Â´Ù.
#ifdef PACKET_SAMPLE3
    DoRecv(sock);
    DoRecv(sock);
#endif

flatbuffersÀÇ Å©±â¸¦ ¹Þ´Â´Ù.
int len = recv(sock, (char*)&buffLen, 4, 0);

¹öÆÛ¸¦ »ý¼ºÇÏ°í ¹öÆÛ Å©±â ¸¸Å­ ³×Æ®¿÷À¸·Î ¼ö½ÅÇÑ´Ù.
std::unique_ptr<uint8_t[]> buff(new uint8_t[buffLen]);
len = recv(sock, (char*)buff.get(), buffLen, 0);

DeserializeUnion ÇÔ¼ö¿¡¼­ À̺¥Æ® ŸÀÔ¿¡ µû¶ó ÆÐŶÀ» ó¸®ÇÑ´Ù.

int DoRecv(SOCKET sock)
{
    int buffLen = 0;
    int len = recv(sock, (char*)&buffLen, 4, 0);
    if (len == -1)
    {
        ErrorHandling("recv buffer length Error\n");
        return -1;
    }

    std::unique_ptr<uint8_t[]> buff(new uint8_t[buffLen]);
    len = recv(sock, (char*)buff.get(), buffLen, 0);
    if (len == -1)
    {
        ErrorHandling("recv buffer Error\n");
        return -1;
    }
    DeserializeUnion(buff.get(), buffLen);

    return 0;
}

void DeserializeUnion(uint8_t* data, int deBufSize)
{
    flatbuffers::Verifier verifier(data, deBufSize);
    bool res = MyEvent::VerifyEventHolderBuffer(verifier);
    if (res)
    {
        auto eventHolder = MyEvent::GetEventHolder(data);
        if (eventHolder->event_type() == MyEvent::EventCmd_EventStart)
        {
            const MyEvent::EventStart* e = eventHolder->event_as<MyEvent::EventStart>();
            std::cout << "MyEvent::EventStart  " << "¾ÆÀ̵ð : " << e->id() << std::endl;
            std::cout << "MyEvent::EventStart  " << "ŸÀÓ : " << e->time() << std::endl;
        }
        else if (eventHolder->event_type() == MyEvent::EventCmd_EventEnd)
        {
            const MyEvent::EventEnd* e = eventHolder->event_as<MyEvent::EventEnd>();
            if (e == nullptr)
            {
                printf("\n EventEnd is nullptr\n");
            }
            else
            {
                int id = e->id();
                std::cout << "MyEvent::EventEnd ¾ÆÀ̵ð : " << e->id() << std::endl;
                std::cout << "MyEvent::EventEnd ¸Þ¼¼Áö : " << e->message()->c_str() << std::endl;
            }
        }
    }
}


Ŭ¶óÀ̾ðÆ® ½ÇÇà °á°ú

MyEvent::EventStart  ¾ÆÀ̵ð : 100
MyEvent::EventStart  ŸÀÓ : 0.8
MyEvent::EventEnd ¾ÆÀ̵ð : 5
MyEvent::EventEnd ¸Þ¼¼Áö : quit5

SOCKET OVER

´Ù¿î·Îµå:
server.cpp
client.cpp
flatbuffers_networkTest.zip

Âü°í)
flatbuffer ÆÐŶ º¸³»±â
https://copynull.tistory.com/416?category=194491
https://swjman.tistory.com/12
https://zepeh.tistory.com/517
https://gall.dcinside.com/mgallery/board/view/?id=game_dev&no=2599

µ¥ÀÌÅ͸¦ º¸³¾¶§´Â FinishSizePrefixed¸¦ »ç¿ë ¹ÞÀ»¶§´Â 4byte·Î ÆÐŶũ±â¸¦ üũÈÄ ³ª¸ÓÁö¸¦ ¹Þ´Â´Ù.
https://blog.csdn.net/guotianqing/article/details/100691267

union Á¤ÀÇ
https://zepeh.tistory.com/517
https://www.huaweicloud.com/articles/cab74552246ce06561b24873d4d7c07e.html
https://base64.work/so/c%23/1073875

FlatBuffers + Boost Asio ¼­¹ö ¿¹Á¦
https://copynull.tistory.com/414