본문 바로가기
c#

기본 연결이 닫혔습니다. 보내기에서 예기치 않은 오류가 발생했습니다.

by ┌(  ̄∇ ̄)┘™ 2023. 11. 7.
728x90
728x90

C#에서 HttpWebRequest로 HTTPS 통신을 하다가 다음 예외를 만나는 경우가 있습니다.

기본 연결이 닫혔습니다. 보내기에서 예기치 않은 오류가 발생했습니다.
(The underlying connection was closed: An unexpected error occurred on a send.)

보통 httpRequest.GetResponse()를 호출하는 순간 터집니다.

var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
// → 기본 연결이 닫혔습니다. 보내기에서 예기치 않은 오류가 발생했습니다.

원인 — TLS 버전 불일치

대부분의 원인은 TLS 프로토콜 협상 실패입니다. 구버전 .NET Framework는 기본적으로 SSL 3.0 / TLS 1.0으로 핸드셰이크를 시도하는데, 요즘 서버들은 보안상 TLS 1.2 미만 연결을 거부하기 때문에 연결이 그대로 끊깁니다. 해결은 요청 전에 사용할 보안 프로토콜을 TLS 1.2로 지정하는 것입니다.

해결 — 프레임워크 버전별 코드

.NET Framework 4.5 이상 — Tls12 열거형을 그대로 사용합니다.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

.NET Framework 4.0 이하 — 열거형에 Tls12 값이 없으므로 정수 값(3072)을 캐스팅합니다.

// TLS 1.2의 정수 값 = 3072 (0xC00)
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

적용 시 주의점

  • 이 설정은 요청을 보내기 전에, 애플리케이션 시작 시 한 번 실행하는 것이 좋습니다 (예: Global.asax, Main 진입점).
  • ServicePointManager.SecurityProtocol프로세스 전역 설정이므로, 앱 안의 모든 HTTP 통신에 영향을 줍니다.
  • 여러 프로토콜을 동시에 허용하려면 비트 OR로 조합합니다 — SecurityProtocolType.Tls12 | (SecurityProtocolType)12288 (12288 = TLS 1.3).
  • .NET 4.7 이상은 OS 기본 프로토콜을 따르므로 이 코드가 필요 없는 경우가 많습니다. 근본 해결은 프레임워크 업그레이드입니다.

레지스트리 차원의 OS 설정까지 포함한 전체 절차는 구 닷넷프레임워크 버전에서 TLS1.2 사용 절차 글에서 이어집니다.

728x90

댓글