일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- MVVM
- MS-SQL
- Animation
- db
- JavaScript
- Binding
- AnimationController
- 자바스크립트
- typescript
- listview
- Flutter
- 닷넷
- spring boot
- 리엑트
- MSSQL
- Maui
- React JS
- 함수
- 플러터
- 마우이
- 바인딩
- HTML
- 파이어베이스
- 깃허브
- 애니메이션
- page
- 오류
- Firebase
- GitHub
- .NET
- Today
- Total
개발노트
11. [ASP .NET Core] TCP Server 만들기 (백그라운드 서비스, DI로 자동 주입) 본문
11. [ASP .NET Core] TCP Server 만들기 (백그라운드 서비스, DI로 자동 주입)
mroh1226 2025. 3. 28. 21:20개요
이번 글에서는 .NET Core의 IHostedService와 BackgroundService를 활용하여 TCP 서버를 백그라운드 서비스로 구현하는 방법을 소개합니다. TCP 서버를 구축하고, 백그라운드 서비스에서 이를 실행하는 방식과 종속성 주입(DI)으로 관리하는 원리를 설명합니다.
1. TCP 서버란?
TCP 서버는 클라이언트와의 연결을 유지하면서 데이터를 송수신하는 서버입니다. .NET Core에서는 TcpListener와 TcpClient를 사용하여 TCP 서버를 구축할 수 있습니다.
이 글에서는 TcpServer 클래스를 만들어서 클라이언트의 요청을 받고, 해당 메시지를 그대로 응답하는 간단한 TCP 서버를 구현합니다.
2. TCP 서버 구현하기
TcpServer 클래스 (IHostedService 구현)
TcpServer는 IHostedService를 구현하여 백그라운드에서 실행되도록 합니다.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
namespace NetworkService
{
public class TcpServer : IHostedService
{
private TcpListener _listener;
private CancellationTokenSource _cts;
public async Task StartAsync(CancellationToken cancellationToken)
{
var port = 2222;
var hostAddress = IPAddress.Parse("127.0.0.1");
_listener = new TcpListener(hostAddress, port);
_listener.Start();
Console.WriteLine("TCP 서버 시작됨.");
while (!cancellationToken.IsCancellationRequested)
{
try
{
// 클라이언트 연결 대기
using TcpClient client = await _listener.AcceptTcpClientAsync();
Console.WriteLine($"클라이언트 연결됨: {client.Client.RemoteEndPoint}");
_ = HandleClientAsync(client);
}
catch (Exception ex)
{
Console.WriteLine($"오류 발생: {ex.Message}");
}
}
}
private async Task HandleClientAsync(TcpClient client)
{
using var tcpStream = client.GetStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = await tcpStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
// 클라이언트로부터 받은 메시지 출력
string receivedMessage = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine($"수신됨: {receivedMessage}");
// 받은 메시지를 그대로 응답
byte[] response = Encoding.UTF8.GetBytes(receivedMessage);
await tcpStream.WriteAsync(response, 0, response.Length);
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
_listener?.Stop();
Console.WriteLine("TCP 서버 종료됨.");
return Task.CompletedTask;
}
}
}
위 코드에서는 TCP 서버를 시작(StartAsync)하고, 클라이언트가 연결되면 데이터를 송수신하는 역할을 합니다.
TCP 통신은 스트림 기반으로 데이터를 전송합니다. 클라이언트와 서버 간에 주고받는 데이터를 처리할 때, 스트림을 사용해 바이트 단위로 데이터를 송수신합니다.
- 클라이언트로부터 데이터를 수신하기 위해 버퍼(byte[] buffer)를 사용하여 일정 크기만큼 데이터를 읽고, 읽은 데이터를 바이트 배열로 처리합니다.
- 받은 데이터를 그대로 클라이언트에게 다시 송신할 때도 버퍼를 사용하여 송신합니다
이 코드에서 tcpStream.ReadAsync로 데이터를 읽고, tcpStream.WriteAsync로 데이터를 송신하는 부분이 바로 스트림을 통한 통신입니다. 데이터를 읽을 때는 버퍼를 사용해 일정 크기만큼 읽고, 받은 데이터를 그대로 응답하는 방식입니다
3. 백그라운드 서비스로 실행하기
TcpWorker 클래스 (BackgroundService 구현)
TcpWorker는 BackgroundService를 상속받아 백그라운드에서 TcpServer를 실행합니다. 또한, 종료되면 다시 실행되도록 처리합니다.
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace NetworkService
{
public class TcpWorker : BackgroundService
{
private readonly ILogger<TcpWorker> _logger;
private readonly TcpServer _tcpServer;
public TcpWorker(ILogger<TcpWorker> logger, TcpServer tcpServer)
{
_logger = logger;
_tcpServer = tcpServer;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
await _tcpServer.StartAsync(stoppingToken);
}
catch (Exception ex)
{
_logger.LogError($"TCP 서버 오류: {ex.Message}");
}
finally
{
_logger.LogInformation("TCP 서버가 중지됨, 재시작 시도");
await Task.Delay(5000, stoppingToken);
}
}
}
}
}
TcpWorker에서 TcpServer 시작
TcpWorker는 BackgroundService를 상속받아 구현됩니다. BackgroundService는 백그라운드에서 주기적으로 실행될 작업을 정의할 수 있습니다. TcpWorker는 TcpServer의 StartAsync 메서드를 호출하여 TCP 서버가 시작되도록 합니다.
TcpWorker는 백그라운드에서 계속 실행되며, stoppingToken이 취소될 때까지 TcpServer를 실행합니다. 만약 서버가 오류로 종료되면, finally 블록에서 5초 후에 다시 서버를 시작하는 방식으로 자동 재시작을 시도합니다.
자동 종속성 주입(DI) 동작
DI는 TcpWorker와 TcpServer 간의 의존성을 해결합니다. TcpWorker는 생성자에서 TcpServer를 주입받으며, TcpServer의 인스턴스는 DI 컨테이너에서 자동으로 관리됩니다. TcpServer는 생성자 없이도 DI를 통해 등록되므로, 별도로 인스턴스를 생성할 필요 없이 자동으로 관리됩니다.
4. DI (종속성 주입)으로 TCP 서버 등록하기
TCP 서버와 백그라운드 서비스를 DI 컨테이너에 등록하여 관리할 수 있습니다.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace NetworkService
{
class Program
{
static async Task Main(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
services.AddSingleton<TcpServer>(); // TCP 서버 싱글톤 등록
services.AddHostedService<TcpWorker>(); // 백그라운드 서비스 등록
})
.ConfigureLogging(logging =>
{
logging.AddConsole();
logging.SetMinimumLevel(LogLevel.Debug);
})
.Build();
await host.RunAsync();
}
}
}
DI 등록 원리
TcpServer는 IHostedService를 구현하여 백그라운드 서비스로 실행되며, DI를 통해 등록됩니다. DI 등록은 ConfigureServices 메서드에서 이루어집니다.
- services.AddSingleton<TcpServer>()는 TcpServer를 싱글톤으로 등록합니다. 즉, 애플리케이션이 실행되는 동안 하나의 인스턴스만 존재하게 됩니다.
- services.AddHostedService<TcpWorker>()는 백그라운드 서비스로 TcpWorker를 등록하여, 애플리케이션이 시작될 때 자동으로 TcpWorker가 실행되도록 합니다.
- services.AddSingleton<TcpServer>();
- TCP 서버 인스턴스를 싱글톤으로 등록하여 애플리케이션이 실행되는 동안 유지됩니다.
- services.AddHostedService<TcpWorker>();
- 백그라운드 서비스로 TcpWorker를 등록하여 TcpServer를 실행하도록 합니다.
- Host.CreateDefaultBuilder()
- 기본적인 호스팅 환경을 설정합니다.
- 로그 설정 및 DI 컨테이너를 초기화합니다.
- await host.RunAsync();
- 호스트를 실행하여 백그라운드 서비스가 지속적으로 실행되도록 합니다.
5. 마무리
- TcpServer는 클라이언트와의 통신을 처리하는 핵심 클래스이며, TcpListener와 TcpClient를 사용하여 클라이언트와 연결을 유지하면서 데이터를 송수신합니다.
- 버퍼는 데이터 송수신 시 효율적으로 작업하기 위해 사용됩니다. 스트림 기반 통신에서 데이터를 읽고 쓰는 데 중요한 역할을 합니다.
- **DI (종속성 주입)**는 TcpServer와 TcpWorker가 자동으로 연결되도록 합니다. TcpServer는 DI 컨테이너에서 관리되며, TcpWorker는 TcpServer를 주입받아 백그라운드에서 실행합니다.
- TcpWorker는 백그라운드 서비스로 TcpServer를 실행하고, 서버가 종료되면 자동으로 다시 실행되도록 합니다.
이 과정은 IHostedService와 BackgroundService의 결합을 통해 백그라운드에서 지속적으로 실행되는 TCP 서버를 구성하는 방법입니다. TcpServer는 별도의 생성자 없이 DI 등록만으로 자동으로 실행되므로, 개발자가 직접 인스턴스를 생성할 필요가 없습니다.
'서버 개발 > ASP .NET Core' 카테고리의 다른 글
12. [ASP .NET Core] TcpClient (Winform 으로 클라 만들기) (0) | 2025.03.28 |
---|---|
10. [ASP .NET Core] Json으로 객체 직렬화 시, 빈 값으로 매핑되는 문제 (0) | 2025.03.25 |
9. [ASP .NET Core] 닷넷에서 웹 파일로 띄우기 (0) | 2025.03.25 |
8. [ASP .NET Core] 누겟말고 소스 (0) | 2025.02.19 |
7. [ASP .NET Core] HttpClient 올바르게 사용하기 (0) | 2025.02.03 |