본문 바로가기
개인 스터디

비동기 TCP 서버

by 태운콩즙 2024. 10. 17.
728x90
반응형

TCP 서버는 동기 적으로 TCP 서버로서 이는 동시에 여러 클라이언트들 이 접속 했을 때 순차적으로 하나 씩 처리해야 하는 단점이 있다 따라서 다중 클라이언트 접속을 핸들링 하기 위해서는 TCP 서버를 비동기로 만들 필요가 있다 TCP 서버를 비동기로 만드는 방법은 크게 두 가지로 분류 할 수 있는데 고전적인 APM 방식과 요즘 많이 사용되는 TAP 방식이 있다

APM 방식은 BeginAcceptTcpClient()/EndAcceptTcpClient() dhk rkxdl Begin/End* 2개의 메서드를 쌍으로 사용하는 방식으로 Backward Compatibility 를 위해 사용 된다 TAP 방식은 AcceptTcpClientAsync() 와 같이 Async 가 붙는 메서드를 C# await 와 함께 사용하는 방식으로 비동기 처리를 단순화한 현대적 방식이다.

TAP비동기 TCP 서버 사용 예제

TAP 방식을 사용하여 간단한 비동기 TCP 서버를 작성한 예제를 살펴보자 먼저 동시에 여러 클라이언트들이 접속할 때 각 클라이언트 별로 독립적인 쓰레드를 사용하여 동작하도록 하기 위해 TcpListener 객체에 AcceptTcpClientAsync() 메서드를 호출 한다 이 메서드를 C# await로 사용하여 클라이언트 Connection을 비동기로 받아들이도록 한다 새로 연결된 클라이언트는 새로운 작업 쓰레드에서 처리를 담당한다 또한 데이터 송수신 시 NetworkStream의 ReadAsync(), WriteAsync() 메서드를 사용하여 비동기로 네트워크 스트림 에 데이터를 읽고 쓰게 할 수 있다.

using System.Net.Sockets;
using System.Net;
using System;
using System.Threading.Tasks;
using System.Text;

namespace ConsoleApp1
{

    class Program
    {
        static void Main(string[] args)
        {
            AysncEchoServer().Wait();
        }

        async static Task AysncEchoServer()
        {
            TcpListener listener = new TcpListener(IPAddress.Any, 7000);
            listener.Start();
            while (true)
            {
                // 비동기 Accept                
                TcpClient tc = await listener.AcceptTcpClientAsync().ConfigureAwait(false);

                // 새 쓰레드에서 처리
                Task.Factory.StartNew(AsyncTcpProcess, tc);
            }
        }

        async static void AsyncTcpProcess(object o)
        {
            TcpClient tc = (TcpClient)o;

            int MAX_SIZE = 1024;  // 가정
            NetworkStream stream = tc.GetStream();

            // 비동기 수신            
            var buff = new byte[MAX_SIZE];
            var nbytes = await stream.ReadAsync(buff, 0, buff.Length).ConfigureAwait(false);
            if (nbytes > 0)
            {
                string msg = Encoding.ASCII.GetString(buff, 0, nbytes);
                Console.WriteLine($"{msg} at {DateTime.Now}");

                // 비동기 송신
                await stream.WriteAsync(buff, 0, nbytes).ConfigureAwait(false);
            }

            stream.Close();
            tc.Close();
        }
        
    }
}
728x90
반응형

'개인 스터디' 카테고리의 다른 글

영업 관리 시스템  (0) 2024.11.14
Monitor  (0) 2024.10.16
스핀락  (0) 2024.10.16
C# Thread(스레드) 주요 속성과 메서드  (0) 2024.10.15
무명 메서드 (Anonymous Method)  (0) 2024.10.14