개인공부) 서버실습(34) - List Packet

Justin·2022년 6월 29일
0

서버공부

목록 보기
33/45
post-thumbnail

지난 시간

int, short 같은 사이즈 크기가 정해져있는 것과 다르게 string 타입은 입력 값에 따라 변하기에 다른 방법으로 처리를 해주어여했다. 하지만 새로운 방법이 아닌 기존 처럼 string을 얼마나 사용할 건지 미리 넘겨주고, 그 만큼 메모리에 할당하는 방식을 사용해 재미있게 사용해볼 수 있었다.

list Packet

그렇다면 list Packet은 어떻게 넘길 수 있을까? 우선 예시를 위해 기존 작업하던 PlayerInforReq class내에 list를 만들어 주자

public List<SkillInfo> skills = new List<SkillInfo>();
{

}

public struct SkillInfo
        {
            int id;
            short level;
            float duration;
        }

구조체(struct) 타입으로 list를 만들고, SkillInfo 안에 스킬의 id, level, duration을 담아준다.

Write() 추가

Write라는 함수를 만들어 span과 ref로 count를 받아서 각 스킬의 id, level, duration을 byte 타입으로 넘겨준다. bool 값을 return 해주어 혹시 모를 에러를 방지한다.

PlayerInforReq.Write()


PlayerInforReq.Write 내부로 이동하여 기존 작업하던 곳 하단에 새로 skills.count를 받아와 미리 list의 크기를 넣어주고

skills.count를 그냥 넣으면 int 타입이기에 4바이트가 들어간다. 앞에 ushort를 추가하여 꼭 캐스트를 해주자

스킬이 여러개 일 수 있기에 foreach를 통해 list를 돌면서 인코딩 작업을 해준다.

Read() 추가

SkillInfo 내에 Read()를 만들어 기존 Read에서 사용했던 ReadOnlySpan, count를 받아와서 id, level, duration을 읽어 준다.

float 값은 변환할 떄 할 때 BitConverter.ToSingle 키워드를 사용해주면 된다.

PlayerInforReq.Read()

PlayerInforReq로 돌아와서 우선 list의 크기를 받고, count 사이즈를 올려준 뒤 역시 for문을 돌며 skill을 담아준다.

왜 Read인데 Add를 해줄까?
메시지를 읽는 서버 쪽에서는 구조체에 담긴 데이터가 없기에 Add를 통해 어떤 데이터가 들어왔는지 담아주어야한다.

테스트

연결이 되며(OnConnected) 패킷을 전송할 때 새로운 스킬들을 잔뜩 만들어 넣어준다.

전송받은 패킷을 읽어오는 쪽에도 foreach로 받아오면

정상적으로 잘 넘어간 것을 확인할 수 있다.

위 방법은 아주 간단하게 패킷을 넘겨주는 방법이고, 패킷을 보내는게 많지 않으면 간단하게 위와 같이 처리해도 된다.

하지만 아니라면 자동화를 해주어야 한다.


일반적으로 Serialization을 할 때에 자주 사용되는 라이브러리가 두 가지 있다.

프로토 버프, 플랫 버프

프로토 버퍼
구글 제작 위에서 list에 Add로 skill의 정보를 넣는 방식 처럼 중간에 인스턴스하여 넣는 방식.

성능 상에 손해는 발생하겠지만 직관적이고 관리하기 편하기에, 약간의 손해를 감수하더라도 사용할만하다.

플랫 버퍼
배열에 담아 한 번에 전송하는 방식으로 가독성은 좋아지지만 어떤 부분에 문제가 생긴 것인지 직관적으로 파악하기가 어렵다.

profile
인디 게임을 만들며 공부하고 있습니다.

0개의 댓글