StackOverflow 예외와 TCP 연결 수신의 관계
.NET 애플리케이션에서 StackOverflowException 발생 시 TCP 연결 수신 가능 여부는 런타임 버전과 예외 발생 위치에 따라 달라집니다. 일반적으로 .NET Core/.NET 5+ 환경에서는 프로세스가 즉시 종료되며, .NET Framework에서는 특정 조건에서 부분적 동작이 가능합니다.
.NET Core/.NET 5+의 처리 방식
- StackOverflowException은 try-catch 블록으로 포착 불가능
- 예외 발생 시 즉시 프로세스 종료 (환경변수 COMPlus_EnableSO 설정 시 제외)
- 모든 TCP 연결 수신 및 처리 기능 정지
.NET Framework의 특수한 동작
- 비주요 스레드에서 예외 발생 시 프로세스 생존 가능
- TCP 수신 전용 스레드가 독립적으로 동작할 경우 연결 수신 지속
- 주 스레드 또는 시스템 핵심 스레드 영향 시 전체 프로세스 종료
TCP 수신 지속 조건 및 메커니즘
다음 조건에서 .NET Framework 기반 애플리케이션은 TCP 연결을 계속 수신할 수 있습니다:
- TCP 수신기가 전용 스레드에서 실행 중일 때
- StackOverflowException이 클라이언트 처리 스레드에서만 발생할 때
- 예외로 인한 리소스 손상이 네트워크 스택에 미치지 않을 때
TCP 수신기 구현 예제
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class NetworkServer
{
private TcpListener _listener;
public void Start(int port)
{
_listener = new TcpListener(IPAddress.Any, port);
_listener.Start();
var listenThread = new Thread(ConnectionHandler);
listenThread.IsBackground = true;
listenThread.Start();
}
private void ConnectionHandler()
{
try
{
while (true)
{
var client = _listener.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(ProcessConnection, client);
}
}
catch (Exception ex)
{
Console.WriteLine($"수신 오류: {ex.Message}");
}
}
private void ProcessConnection(object state)
{
using (var client = (TcpClient)state)
{
// 클라이언트 처리 로직
}
}
}
예외 발생 시나리오별 영향
| 예외 위치 | .NET Framework 영향 | .NET Core 영향 |
|---|---|---|
| TCP 수신 스레드 | 연결 수신 불가 | 프로세스 종료 |
| 클라이언트 처리 스레드 | 해당 연결만 실패 | 프로세스 종료 |
| 주 실행 스레드 | 프로세스 종료 | 프로세스 종료 |
문제 방지 전략
- 재귀 호출 대신 반복문 사용
- 스택 깊이 모니터링 클래스 구현:
public class RecursionGuard { private int _currentDepth; private readonly int _maxDepth; public RecursionGuard(int maxDepth = 100) { _maxDepth = maxDepth; } public void Execute(Action action) { _currentDepth++; if (_currentDepth > _maxDepth) throw new InvalidOperationException("최대 재귀 깊이 초과"); action(); _currentDepth--; } } - 프로세스 모니터링 도구(systemd, Kubernetes)를 통한 자동 복구
- 네트워크 작업 전용 격리된 AppDomain 사용
결론 및 권장 접근법
.NET Framework 환경에서는 TCP 수신 스레드의 격리로 StackOverflowException 발생 시 연결 수신이 가능하나, .NET Core 이상 버전에서는 불가능합니다. 신뢰성 있는 서비스 운영을 위해서는:
- .NET Core 런타임 사용 시 외부 모니터링 시스템으로 자동 재시작 구현
- 재귀 호출보다 반복 구조 우선 사용
- 주요 기능별 독립적 스레드 관리