패킷 직렬화
지난 시간에는 ushort, int 자료형과 같이 크기가 정해져 있는 자료형과는 다른 string 자료형의 패킷 Write, Read에 대해서 알아보았다. 이는 크게 2가지의 방법으로 나뉘어져 있는데, 먼저 String Packet의 사이즈를 확인하고 그 다음 내부 데이터 값을 전송하는 방법이었다.
그렇다면 오늘은 String에서 더 나아가 List 자료구조를 보낼 때에는 어떻게 처리해야 하는지에 대해서 학습해본다.
💷 List Packet
그렇다면 List Packet은 어떻게 넘겨줄 수 있을까? 예시를 들어 설명하기 위해 기존에 작업하던 PlayerInfoReq 클래스에 새로운 List를 추가하자.
public List<SkillInfo> skills = new List<SkillInfo>();
{
}
public struct SkillInfo
{
int id;
short level;
float duration;
}
그냥 List에 int, double과 같은 자료형을 넣어서 사용한다면 String과 별반 다를 것이 없기 때문에 구조체(Struct)를 만들어 List를 만들고, SkillInfo 구조체 안에는 스킬의 Id, Level, Duration에 관한 정보를 담아준다.
🧻 SkillInfo 클래스 내 Write
SkileInfo 클래스 내부에 Wirte라는 함수를 새롭게 만들어 준다. 여태까지 Span을 이용하여 작업하였기 때문에 Span을 받아 처리하며, ref 키워드를 이용해 count를 받아 각 스킬의 Id, Level, Duration을 각자의 타입으로 받아와 넘겨준다. 혹시 모르는 bool 변수를 두어 해당 값을 이용해 에러를 방지하여 준다.
🩳 PlayerInfoReq 클래스 내 Write
PlayerInfoReq Wirte 메서드 내부로 이동하여 기존에 작업하돈 곳 하단에 새롭게 skills.Count를 받아와 미리 List의 크기를 넣어서 할당해주고, 스킬이 여러개일 수 있으므로 foreach문을 통해 List를 순회하며 인코딩 작업을 진행한다.
skills.count를 그냥 넣어주게 될 경우 int 타입으기에 4바이트가 들어가게 된다. 반드시 앞에 ushort를 추가하여 캐스팅을 해주자.
🧻 SkillInfo 클래스 내 Read
SkillInfo 내 Read 메서드를 Write 메서드와 같이 새롭게 만들어준다. 기존 PlayerInfoReq 클래스 내부에서 사용했던 ReadOnlySpan 및 count를 받아와 SkillInfo의 Id, Level, Duration을 읽어서 확인한다.
float 자료형은 변환할 대에 BitConverter.ToSing 키워드를 이용하여 처리한다.
🩳 PlayerInfoReq 클래스 내 Read
PlayerInfoReq 클래스로 다시 돌아와 먼저 List의 크기를 받고, count의 사이즈 만큼 올려준 뒤 역시 for문을 순회하며 skill을 담아준다.
왜 Read인데, Add를 해줘야 할까?
메시지를 읽는 서버 쪽에서는 구조체에 담긴 데이터가 없기 때문에 Add를 통해서 데이터가 들어왔는지 알 수 있기 때문에 Add를 해줘야 한다.
실행 결과 😎
패킷을 전송할 때에는 기존 스킬 말고 새로운 스킬도 다양하게 추가하여 넣어준다.
마찬가지로 전송받은 패킷을 읽어오는 쪽에서도 아래 이미지와 같ㅇ foreach문을 통해 이를 받는다면
정상적으로 실행되는 것을 볼 수 있다. 👍
P.S
일반적으로 Serialization 할 떄에 자주 사용되는 라이브러리 2가지가 있다. 바로 프로토 버퍼와 플랫 버퍼이다.
프로토 버퍼
구글에서 제작한 방법. 우리가 작업했던 것과 같이 List에 Add로 skill의 정보를 넣는 방식이다. 즉 중간에 인스턴스하여 넣는 방식. 이는 성능 상에 손해는 발생하겠지만 보다 직관적이고 관리하기 편하기에, 약간의 손해를 감수하더라도 사용할만하다.
플랫 버퍼
배열에 담아 한 번에 전송하는 방식으로 가독성은 좋아지지만 어떤 부분에 어떠한 문제가 생긴 것인지 프로토 버퍼에 비해 직관적으로 파악하기가 어렵다.
'공부 > 인프런 - Rookiss' 카테고리의 다른 글
Part 4-4-7. 패킷 직렬화 : Packet Generator #2 (0) | 2023.12.18 |
---|---|
Part 4-4-6. 패킷 직렬화 : Packet Generator #1 (1) | 2023.12.08 |
Part 4-4-4. 패킷 직렬화 : Serialization #3 (1) | 2023.12.06 |
Part 4-4-3. 패킷 직렬화 : UTF-8 vs UTF-16 (1) | 2023.12.06 |
Part 4-4-2. 패킷 직렬화 : Serialization #2 (0) | 2023.12.04 |