본문 바로가기
cs공부/네트워크프로그래밍

네트워크 프로그래밍 - List 자료형 packet에 넣는 법

by 코딩하는 돼징 2023. 8. 17.
반응형

List안에 기본 int와 같은 자료형이 있는 경우 string, byte넘긴거와 마찬가지 List 몇개 있는지 밀어넣고 데이터를 밀어넣으면 된다.

 

List안에 구조체가 있는 경우 

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

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

List가 몇개인지 short로 밀어 넣고 data를 밀어넣기


1. Write

01 크기 정보 기록

skills List의 요소 개수를 ushort로 변환하여 기록한다.

success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), (ushort)skills.Count);
count += sizeof(ushort);

02 skills List의 각 SkillInfo 구조체를 순회하면서 데이터를 바이트 배열에 기록

foreach(SkillInfo skill in skills)
{
    // skill마다 데이터를 밀어넣어주는 작업이 필요
}

03 SkillInfo의 Write 메서드

Write메서드는 각 SkillInfo구조체의 데이터를 바이트 배열에 기록하는 역할을 한다. id,level,duration 각각의 값을 바이트 배열에 기록하고 count변수를 업데이트 한다.

public bool Write(Span<byte> s, ref ushort count)
{
    bool success = true;
    success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), id);
    count += sizeof(int);
    success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), level);
    count += sizeof(short);
    success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), duration);
    count += sizeof(float);

    return success;
}

04 skill마다 데이터를 밀어넣어주는 작업이 필요

skills리스트에 있는 각 SkillInfo구조체의 데이터를 바이트 배열로 변환하면서 Write메서드를 호출하여 각 SkillInfo의 데이터를 바이트 배열에 기록한다.

foreach(SkillInfo skill in skills)
{
    success &= skill.Write(s, ref count);
}

sucess변수가 하나라도 false이 되면 최종 결과로 false를 반환하도록 한다. 이를 통해 SkillInfo의 데이터가 성공적으로 기록되었는지 확인할 수 있다.


2. Read

01 SkillInfo의 Read

SkillInfo의 Read메서드는 바이트 배열로부터 데이터를 읽어와 SkillInfo구조체의 필드에 저장하는 역할을 한다. 각 필드에 대한 데이터를 바이트 배열로부터 읽어와 count변수를 업데이트 한다.

public struct SkillInfo
{
    public void Read(ReadOnlySpan<byte> s, ref ushort count)
    {
        id = BitConverter.ToInt32(s.Slice(count, s.Length - count));
        count += sizeof(long);
        level = BitConverter.ToInt16(s.Slice(count, s.Length - count));
        count += sizeof(short);
        duration = BitConverter.ToSingle(s.Slice(count, s.Length - count));
        count += sizeof(float);
    }
}

02 skill list parsing

Read메서드는 skills List를 파싱하며 각 SkillInfo구조체를 생성하고 읽어온 데이터를 저장한다.

public override void Read(ArraySegment<byte> openSegment)
{
    ushort skillLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
    count += sizeof(ushort);
    skills.Clear();
    for(int i = 0; i < skillLen; i++)
    {
        SkillInfo skill = new SkillInfo();
        skill.Read(s, ref count);
        skills.Add(skill);
    }
}

1) skillLen

s의 현재위치(count)에서부터 ushort형식으로 크기 정보를 읽어온다. 이는 skills리스트에 있는 SkillInfo 구조체의 개수이다.

ushort skillLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));

2) count변수 업데이트

count += sizeof(ushort);

3) skills.Clear

기존에 skills 리스트에 있는 데이터를 모두 지운다. 이는 데이터를 다시 읽어올 때 기존 데이터와 새로운 데이터를 혼동하지 않기 위해서이다.

skills.Clear();

4) skillLen의 크기만큼 반복하여 SkillInfo구조체 데이터 읽어오기

for(int i = 0; i < skillLen; i++)
{
    SkillInfo skill = new SkillInfo();
    // 바이트 배열 s에서 데이터를 읽어와 skill 객체에 저장
    skill.Read(s, ref count);
    // skill 객체를 skills 리스트에 추가
    skills.Add(skill);
}

3. 결과

 

 

 

 

 

 

참고 :  본 내용은 MMORPG  PART4 강의를 수강하여 작성하였습니다.

https://www.inflearn.com/course/%EC%9C%A0%EB%8B%88%ED%8B%B0-mmorpg-%EA%B0%9C%EB%B0%9C-part4

 

 

 

 

반응형

댓글