UnityServer - PacketSession

k_hyun·2022년 11월 3일
0

Unity_Server

목록 보기
22/32

Session.cs

public abstract class PacketSession : Session
    {
        public static readonly int HeaderSize = 2;
        // [size(2)][packetId(2)][ ... ][size(2)][packetId(2)][ ... ]
        public sealed override int OnRecv(ArraySegment<byte> buffer)
        {
            int processLen = 0;

            while (true)
            {
                // 최소한 헤더는 파싱할 수 있는지 확인
                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);
    }

기존의 OnRecv함수는 sealed override를 통해 받은 패킷을 파싱하는데 사용하였다.

while문 안에서 패킷 조립이 가능한 곳까지 오면 OnRecvPacket 함수를 실행하도록 하였다.

이후 buffer를 다음 패킷 지점까지 옮겨 작업할 수 있도록 하였다.

Server.cs

		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}");
        }

받은 패킷을 처리하는 OnRecvPacket함수이다.

받은 패킷의 사이즈와 id를 출력하도록 하였다.

Program.cs (DummyClient)

class GameSession : Session
    {
        public override void OnConnected(EndPoint endPoint)
        {
            Console.WriteLine($"OnConnected {endPoint}");

            Packet packet = new Packet() { size = 4, packetId = 7 };

            // 보낸다
            for (int i = 0; i < 5; i++)
            {
                ArraySegment<byte> openSegment = SendBufferHelper.Open(4096);
                byte[] buffer = BitConverter.GetBytes(packet.size);
                byte[] buffer2 = BitConverter.GetBytes(packet.packetId);
                Array.Copy(buffer, 0, openSegment.Array, openSegment.Offset, buffer.Length);
                Array.Copy(buffer2, 0, openSegment.Array, openSegment.Offset + buffer.Length, buffer2.Length);
                ArraySegment<byte> sendBuff = SendBufferHelper.Close(packet.size);

                Send(sendBuff);
            }
        }

사이즈 4, 아이디는 7의 내용을 담은 패킷을 생성하여 서버로 전송하였다.

실행 결과


서버에서 받은 패킷의 내용을 잘 받았음을 확인하였다.

0개의 댓글