반응형
패킷 조립
- 그냥 byte 배열을 보내는 것이 아닌, Size, packetId등을 가진 패킷을 조립해서 넘겨보자
namespace Server
{
class Packet
{ //최대한 크기를 작게 보내자
public ushort size; //2 Byte
public ushort packetId;
}
class GameSession : PacketSession
{
//OnRecv가 PacketSession에서 sealed가 됐으므로, 재정의 불가
//abstract OnRecvPacket을 정의하여 사용
public override void OnRecvPacket(ArraySegment<byte> buffer)
{
ushort size = BitConverter.ToUInt16(buffer.Array, buffer.Offset);
ushort id = BitConverter.ToUInt16(buffer.Array, buffer.Offset + 2);
Console.WriteLine($"RecvPacketId: {id}, Size: {size}");
}
}
}
public abstract class PacketSession : Session
{
public static readonly int HeaderSize = 2;
//sealed를 쓰면 내가 봉인을 했다는 의미
//[size(2)][packetId(2)][...][size(2)][packetId(2)][...]
public sealed override int OnRecv(ArraySegment<byte> buffer)
{
int processLen = 0;
while(true)
{
//최소한 헤더는 파싱할 수 있는지 확인(size-2)
if (buffer.Count < HeaderSize)
break;
//패킷이 완전체로 도착했는지
ushort dataSize = BitConverter.ToUInt16(buffer.Array, buffer.Offset);
if (buffer.Count < dataSize)
break;
//여기까지 왔으면 패킷 조립 가능
OnRecvPacket(new ArraySegment<byte>(buffer.Array, buffer.Offset, dataSize));
processLen += dataSize;
buffer = new ArraySegment<byte>(buffer.Array, buffer.Offset + dataSize, buffer.Count - dataSize); //버퍼 옮기기
}
return processLen;
}
public abstract void OnRecvPacket(ArraySegment<byte> buffer);
}
반응형
'C# > 네트워크' 카테고리의 다른 글
[c#][서버] Unicode & Encoding / UTF8 vs UTF16 (0) | 2024.06.09 |
---|---|
[c#][서버] Serialization (0) | 2024.06.09 |
[c#][서버] RecvBuffer, SendBuffer (1) | 2024.06.07 |
[c#][서버] TCP vs UDP (0) | 2024.06.07 |
[c#][서버] Connector (0) | 2024.06.07 |