네트워크가 갑자기 종료되면 TCP 연결은 어떻게 되나요?

네트워크가 갑자기 종료되면 TCP 연결은 어떻게 되나요?

사용자 공간 애플리케이션에 로컬이 아닌 일부 엔드포인트에 대한 TCP 연결이 있다고 가정합니다. 어떤 시점에서 네트워크 연결이 갑자기 끊어집니다(예: 네트워크 관리자에서 연결 삭제, WiFi 어댑터 분리, 이더넷 케이블 절단).

개념적으로, 이 상황을 처리하기 위해 커널 내부에서는 무슨 일이 일어나고 있으며, 이것이 사용자 공간 애플리케이션에 어떻게 나타납니까?

안내 하위 질문:

  • 어떤 시간 초과가 관련됩니까?
  • 커널은 다시 연결을 시도할 때 사용자 공간에서 연결 손실을 숨기려고 합니까?
  • 응답을 기다리면 사용자 공간 애플리케이션이 정상적으로 종료되지 않게 됩니까?

답변1

네트워크 인터페이스 또는 기타 인프라의 오류가 반드시 "연결 끊김"을 의미하는 것은 아닙니다. TCP는 연결을 종료하기 전에 오랜 시간 동안 재전송을 시도할 수 있습니다(발생한 상황에 따라 다름). 로컬 인터페이스의 오류로 인해 즉각적인 오류가 발생할 수 있지만 그에 따라 경로를 따라 어딘가로 내려가는 A 라우터는 그렇지 않을 수 있습니다).

이는 커널이 아니라 TCP 프로토콜에 의해 결정되며 "사용자 공간 응용 프로그램"은 소켓에서 오류를 수신하기까지 오랜 시간을 기다릴 가능성이 높습니다.

각 하위 질문에 구체적으로 답변하세요.

  • 제한 시간이 초과되기 전 최대 9분에 대한 권장 사항을 본 적이 있습니다(프로토콜이 허용하는 한 이러한 시간 초과 중 일부는 구성 가능하며 TCP keepalive와 같은 항목은 더 일찍 시간 초과를 발생시키도록 구성할 수 있다고 생각합니다).
  • 커널은 내용을 숨기거나 "다시 연결"을 시도하지 않고 단지 TCP 프로토콜을 따르고 승인되지 않은 세그먼트를 보내려고 계속 재시도합니다... "사용자 공간 응용 프로그램"이 시스템 호출(예: write(), sendto())에서 중단됩니다. 등), 즉 "사용자 공간 응용 프로그램"은 커널 모드에서 실행되고 해당 컨텍스트는 전환되며 일부 이벤트가 프로세스를 다시 "실행 가능"하게 만들 때까지 다시 전환되지 않습니다.
  • 중단된 동안 "사용자 공간 응용 프로그램"은 "중단 불가능"할 수 있습니다. 즉, 루트로 SIGKILL(예: Kill -9)을 사용하더라도 이를 종료할 수 없습니다. "우아한 종료"는 옵션이 아닐 수 있습니다(비록 저는 그렇지 않습니다). 그렇게 하십시오) 소켓에서 전송할 때 이런 일이 발생하지 않을 것이라고 생각하면 수명이 짧고 우선 순위가 높은 것으로 간주되어야 합니다. 예를 들어 하드 마운트를 통해 NFS의 파일에 쓰는 경우 intr 플래그가 설정되지 않으면 그렇게 할 수 있습니다. ... 그러나 그것이 옵션이더라도 오류를 포착하고 자체적으로 정상적으로 종료하려면 "응용 프로그램"을 작성해야 합니다. 커널이 "응용 프로그램"을 종료했다면 우아하지 않을 것입니다 :-) (예: 종료 핸들러를 실행하지 않거나 "응용 프로그램" 외부에 할당된 리소스를 해제하지 않습니다.)

관련 정보