반응형
string이나 list같은 가변크기의 패킷을 어떻게 처리하나?
1. string 처리
- 앞에 2바이트를 이 문자열의 크기로 정하고
- 뒤에를 내용으로 채우면 된다.
//string -> len[2b], byte[내용] 로 보내면 되지 않을까
Span<byte> s = new Span<byte>(segment.Array, segment.Offset, segment.Count);
ushort nameLen = (ushort)Encoding.Unicode.GetBytes(this.name, 0, name.Length, segment.Array, segment.Offset + count + sizeof(ushort));
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen);
count += sizeof(ushort); //nameLen의 공간
count += nameLen; //name
//Write 부분
//string
ReadOnlySpan<byte> s = new ReadOnlySpan<byte>(segment.Array, segment.Offset, segment.Count);
ushort nameLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort);
this.name = Encoding.Unicode.GetString(s.Slice(count, nameLen));
//Read 부분
- Write쪽은 일반 Span, Read쪽은 ReadOnlySpan을 활용하여 안정성을 높임
- Encoding.Unicode -> UTF-16 이라는 의미
- GetBytes = string -> Byte배열로 만들어 주는 것, 반환값은 사이즈
- GetString = Byte배열 -> string 변환
2. List 처리
public struct SkillInfo
{
public int id;
public short level;
public float duration;
}
public List<SkillInfo> skills = new List<SkillInfo>();
- 이런 형식의 리스트는 어떻게 처리할까?
public struct SkillInfo
{
public int id;
public short level;
public float duration;
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;
}
public void Read(ReadOnlySpan<byte> s, ref ushort count)
{
id = BitConverter.ToInt32(s.Slice(count, s.Length - count));
count += sizeof(int);
level = BitConverter.ToInt16(s.Slice(count, s.Length - count));
count += sizeof(short);
duration = BitConverter.ToSingle(s.Slice(count, s.Length - count));
count += sizeof(float);
}
}
public List<SkillInfo> skills = new List<SkillInfo>();
- 해당 구조체 안에 함수를 직접 구현하여 사용하게 구현한다
//skill list
skills.Clear();
ushort skillLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort);
for(int i=0; i<skillLen; i++)
{
SkillInfo skill = new SkillInfo();
skill.Read(s, ref count);
skills.Add(skill);
} //Read측
//skill list
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), (ushort)skills.Count);
count += sizeof(ushort);
foreach(SkillInfo skill in skills)
{
success &= skill.Write(s, ref count);
}//Write 측
반응형
'C# > 네트워크' 카테고리의 다른 글
[c#][서버] PacketGenerator(2) (0) | 2024.06.12 |
---|---|
[c#][서버] Packet Generator - 코드 작성 자동화 (2) | 2024.06.09 |
[c#][서버] Unicode & Encoding / UTF8 vs UTF16 (0) | 2024.06.09 |
[c#][서버] Serialization (0) | 2024.06.09 |
[c#][서버] PacketSession (1) | 2024.06.07 |