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();
}
}
}
'개인 스터디' 카테고리의 다른 글
영업 관리 시스템 (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 |