UnityServer - ReceiveAsync

k_hyun·2022년 10월 31일
0

Unity_Server

목록 보기
15/32

세션

세션(session)은 컴퓨터 과학에서, 특히 네트워크 분야에서 반영구적이고 상호작용적인 정보 교환을 전제하는 둘 이상의 통신 장치나 컴퓨터와 사용자 간의 대화나 송수신 연결상태를 의미하는 보안적인 다이얼로그(dialogue) 및 시간대를 가리킨다.

[출처]
https://ko.wikipedia.org/wiki/%EC%84%B8%EC%85%98_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)

Session.cs

    internal class Session
    {
        Socket _socket;
        int _disconnected = 0;            

_disconnected 는 멀티 스레드 환경에서 사용하기 위한 변수이다.

        public void Start(Socket socket)
        {
            _socket = socket;
            SocketAsyncEventArgs recvArgs = new SocketAsyncEventArgs();
            recvArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnRecvCompleted);
            recvArgs.SetBuffer(new byte[1024], 0, 1024);

            RegisterRecv(recvArgs);
        }

recvArgs의 버퍼를 설정하고 등록한다.

        public void Send(byte[] sendBuff)
        {
            _socket.Send(sendBuff);         
        }

        public void Disconnect()
        {
            if (Interlocked.Exchange(ref _disconnected, 1) == 1)
                return;
            _socket.Shutdown(SocketShutdown.Both);
            _socket.Close();
        }

버퍼를 보내고 연결을 끊는 함수이다.

연결을 끊는 것은 멀티 스레드 환경에서 중복적으로 처리될 수 있기 때문에 Interlocked를 사용하였다.

        void RegisterRecv(SocketAsyncEventArgs args)
        {
            bool pending = _socket.ReceiveAsync(args);
            if (pending == false)
                OnRecvCompleted(null, args);
        }

비동기 Receive를 실행한다.

        void OnRecvCompleted(object sender, SocketAsyncEventArgs args)       
        {
            if (args.BytesTransferred > 0 && args.SocketError == SocketError.Success)
            {
                try
                {
                    string recvData = Encoding.UTF8.GetString(args.Buffer, args.Offset, args.BytesTransferred);
                    Console.WriteLine($"[From Client] {recvData}");
                    RegisterRecv(args);
                }
                catch (Exception e)
                {
                    Console.WriteLine($"OnRecvCompleted Failed {e}");
                }
            }
        }

완료되는 경우 args로 부터 데이터를 받아와서 출력한다.

이후 다시 비동기 Receiver를 등록한다.

0개의 댓글