using System.Net.Sockets;
using System.Net;
using System;
using System.Threading.Tasks;
using System.Text;
namespace TcpServerAsync
{
class Program
{
// Main 에서 AysncEchoServer 로 구현된 비동기 로직을 실행한다.
static void Main(string[] args)
{
AysncEchoServer().Wait();
}
// 비동기 서버 로직을 구현한 함수
async static Task AysncEchoServer()
{
// [1] 서버의 Listen 동작을 바로 실행 할 수 있다.
TcpListener listener = new TcpListener(IPAddress.Any, 7000);
listener.Start();
while (true)
{
// 비동기 Accept
TcpClient Connected_TCPClient = await listener.AcceptTcpClientAsync().ConfigureAwait(false);
// 연결된 소켓의 이후 작업은 Task 에서 비동기로 진행되도록 실행 흐름을 분리한다
Task.Factory.StartNew(AsyncTcpProcess, Connected_TCPClient);
}
}
async static void AsyncTcpProcess(object ConnectedSocket)
{
TcpClient tc = (TcpClient)ConnectedSocket;
// [2] 송수신
NetworkStream stream = tc.GetStream();
// 버퍼
int MAX_SIZE = 2048;
var buff = new byte[MAX_SIZE];
// 받는 실행 흐름을 비동기로 동작하게 한다.
var nbytes = await stream.ReadAsync(buff, 0, buff.Length).ConfigureAwait(false);
if (nbytes > 0)
{
string msg = Encoding.UTF8.GetString(buff, 0, nbytes);
Console.WriteLine($"{msg} at {DateTime.Now}");
// 보내는 작없을 비동기로 동작하게 한다. 에코서버라서 받은 데이터를 그대로 보낸다.
await stream.WriteAsync(buff, 0, nbytes).ConfigureAwait(false);
}
// [3] 닫는다.
// 연결이 끊어지지만, 특정 문자이 왔을때 끊어지도록 프로토콜을 로직을 만들면 된다.
stream.Close();
tc.Close();
}
}
}