VisualStudio/C#서버

[C#서버] 구글 프로토 버퍼(Google Protobuf C#)

usingsystem 2022. 11. 18. 15:09
728x90

구글 프로토버퍼란?

Google Protocol Buffers(protobuf)는 데이터 직렬화 형식으로 사용되는 강력하고 효율적인 도구로, 다양한 언어와 플랫폼 간에 데이터를 교환하고 저장하기 위해 사용됩니다. protobuf의 주요 장점은 다음과 같습니다:

  1. 효율적인 직렬화: protobuf는 바이트 크기 측면에서 효율적입니다. 작은 크기의 직렬화된 데이터를 생성하며, 이는 데이터를 네트워크로 전송하거나 디스크에 저장할 때 대역폭과 저장 공간을 절약합니다.
  2. 빠른 역직렬화: protobuf 메시지는 효율적인 이진 형식으로 저장되므로 역직렬화 속도가 빠릅니다. 데이터를 직렬화된 형식에서 메모리 객체로 변환하는 작업이 빠르게 수행됩니다.
  3. 이식성: protobuf는 언어 중립적인 형식으로 데이터를 정의하며, 이로 인해 다양한 프로그래밍 언어와 플랫폼 간에 데이터 교환이 가능합니다. Protocol Buffers는 C++, Java, Python, C#, 등 여러 프로그래밍 언어에서 사용할 수 있는 구현체를 제공합니다.
  4. 스키마 지원: Protocol Buffers는 데이터 스키마를 사용하여 데이터 구조를 정의합니다. 스키마는 데이터 형식 및 필드 구조를 명확하게 정의하므로 데이터 무결성을 유지하고, 버전 간의 호환성을 지원합니다.
  5. 데이터 규모 변화 대응: 스키마 변경을 허용하는 유연성을 제공하므로, 데이터 스키마가 변경되더라도 이전 버전과의 호환성을 유지할 수 있습니다. 이것은 시스템 업데이트 및 업그레이드 시 유용합니다.
  6. 자동 코드 생성: protobuf의 .proto 스키마 파일을 사용하여 각 언어에 대한 코드를 자동으로 생성할 수 있습니다. 이로 인해 데이터 모델과 직렬화 코드를 일관성 있게 유지하기 용이합니다.
  7. 확장성: Protocol Buffers는 필요에 따라 사용자 정의 타입 및 필드를 추가하여 데이터 모델을 확장할 수 있는 메커니즘을 제공합니다.
  8. 안정성: Protocol Buffers는 오버플로우 또는 다른 보안 문제를 방지하는 안전한 직렬화 형식을 사용합니다.
  9. 명시적인 타입: Protocol Buffers는 데이터의 타입을 명시적으로 정의하므로 데이터 변환 및 해석에 관한 혼란을 방지합니다.
  10. 컴팩트한 이진 형식: Protocol Buffers는 사람이 읽기 어려운 텍스트 형식 대신 사람이 읽기 쉬운 이진 형식을 사용합니다.

Google Protocol Buffers는 다양한 응용 프로그램에서 데이터 표현과 교환을 위한 효율적이고 확장 가능한 선택사항으로 널리 사용됩니다.

 

구글 프로토 버퍼 받는 방법

구글 프로토 버퍼 설명 Url

https://developers.google.com/protocol-buffers/docs/csharptutorial

구글 프로토콜 버퍼 변환기 다운로드 Url

https://github.com/protocolbuffers/protobuf/releases/tag/v3.12.3

구글 프로토 사용방법

  • 다운받은 변환기 폴더

  • 적당한 위치에 .proto 파일 생성 

  • 생성한 Protocol.proto에 사용하고 싶은 구조 입력
syntax = "proto3";
package Protocol;

import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Protobuf.Protocol";

message Person {
  string name = 1;
  int32 id = 2;  // Unique ID number for this person.
  string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;

  google.protobuf.Timestamp last_updated = 5;
}

// Our address book file is just one of these.
message AddressBook {
  repeated Person people = 1;
}
  • 배치파일 생성

  • 배치파일에 프로토콜변환 exe 출력 경로 입력(./ 현재경로)
protoc.exe -I=./ --csharp_out=./ ./Protocol.proto
  • 배치파일 실행시 프로토콜 cs파일 생성

  • 사용할 위치에 복사

  • NuGet 패키지 설치 

  • 프로토콜 cs사용하는 방법

Protocol.proto의 구조와 같은 형태로 변환된 cs파일 사용방법은 아래와 같다.

Person person = new Person()
{
    Name= "Test",
    Id = 1,
    Email = "naver.com",
    Phones = { new PhoneNumber { Number = "555-4321", Type = PhoneType.Home } }
};

//응용
ushort size = (ushort)person.CalculateSize();//버퍼사이즈
byte[] sendBuffer = new byte[size + 4]; //+4는 프로토콜 헤더를 위해
Array.Copy(BitConverter.GetBytes(size+4), 0,  sendBuffer, 0, sizeof(ushort));//헤더크기
ushort protocolld = 1;
Array.Copy(BitConverter.GetBytes(protocolld), 0, sendBuffer, 2, sizeof(ushort));//프로토콜id
Array.Copy(person.ToByteArray(), 0, sendBuffer, 4, size);//보낼 데이터
  
//기본
//int size = person.CalculateSize();//버퍼사이즈
//byte[] sendBuffer = person.ToByteArray();//객체를 버퍼로 변경
//Person person2 = new Person();
//person2.MergeFrom(sendBuffer);//버퍼를 객체로 변경

 

 

웹으로 Protocol.proto 사용 방법

https://protogen.marcgravell.com/

 

Protobuf Code Generator and Parser | protobufnet | Marc Gravell

 

protogen.marcgravell.com

 

데이터 타입

Google Protocol Buffers (protobuf)는 데이터 직렬화 및 구조화를 위한 이진 형식의 포맷을 정의하는데 사용되는 플랫폼 중립적인 데이터 직렬화 포맷입니다. protobuf는 .proto 파일을 사용하여 데이터 타입을 정의하고, 해당 정의를 기반으로 데이터를 직렬화하고 역직렬화합니다. 아래는 protobuf에서 사용할 수 있는 일반적인 데이터 타입 목록입니다:

  1. 숫자형 (Numeric Types):
    • double: 부동 소수점 숫자 (64비트)
    • float: 부동 소수점 숫자 (32비트)
    • int32: 32비트 정수
    • int64: 64비트 정수
    • uint32: 부호 없는 32비트 정수
    • uint64: 부호 없는 64비트 정수
    • sint32: 가변 정수 인코딩을 사용하는 32비트 정수
    • sint64: 가변 정수 인코딩을 사용하는 64비트 정수
    • fixed32: 고정 크기 32비트 정수
    • fixed64: 고정 크기 64비트 정수
    • sfixed32: 부호가 있는 고정 크기 32비트 정수
    • sfixed64: 부호가 있는 고정 크기 64비트 정수
  2. 불리언 (Boolean):
    • bool: 참 또는 거짓 값을 나타내는 부울
  3. 문자열 (Strings):
    • string: 유니코드 문자열
  4. 바이트 배열 (Bytes):
    • bytes: 이진 데이터 또는 바이트 배열
  5. 열거형 (Enums):
    • enum: 열거형 상수를 정의하고, 이러한 상수 중 하나를 가질 수 있는 필드를 생성
  6. 메시지 (Message):
    • 사용자 정의 데이터 타입을 정의할 수 있는 메시지 타입을 생성할 수 있습니다. 메시지 내부에 다양한 필드를 포함할 수 있으며, 재귀적으로 다른 메시지 유형을 포함할 수도 있습니다.

protobuf를 사용하여 데이터를 구조화하고 직렬화하면, 다양한 프로그래밍 언어에서 동일한 구조를 사용하여 데이터를 역직렬화하고 처리할 수 있습니다. 이것은 특히 다른 시스템 간 데이터 교환을 위한 효율적인 방법으로 사용됩니다.

728x90