본문 바로가기
츄Log/네트워크 프로그래밍 끄적

TCP 소켓의 TIME_WAIT 상태는 왜 있는 것일까?

by 츄츄🦭 2023. 12. 8.
728x90

 

안녕하세요! 오늘은 소켓의 TIME_WAIT상태에 대해 알아보겠습니다.

 

기본적으로 TCP 통신이라고 하면 "연결 지향"이라는 말이 나오고

"연결"이라는 개념이 나왔다면 서버와 클라이언트를 떠올릴 수 있습니다. 

 

서버와 클라이언트는 연결을 맺고 데이터를 송수신 하다가 연결을 끊게 됩니다. 

 

연결을 끊을 때 four -way handshaking을 하게 되는데요.

(four-way handshaking은 따로 설명하지 않겠습니다.)

X 표시로 소켓 소멸을 표현했습니다.

이 때 먼저 연결을 끊은 측에서 TIME_WAIT 상태에 들어가게 됩니다.

 

클라이언트 소켓이 TIME_WAIT 상태에 들어가는 것이 아니고, 서버 소켓이 TIME_WAIT 상태에 들어가는 것이 아니고,

누구랄 것 없이 먼저 종료를 요청한 소켓이 TIME_WAIT상태에 들어가게 됩니다.

 

그럼 TIME_WAIT은 왜 있는 걸까요?

 

만약 TIME_WAIT상태 없이 클라이언트가 3.FIN을 받고 4.ACK를 보낸 후 바로 소켓을 소멸시켰다고 가정해보겠습니다.

이 때 ACK가 중간에 유실되어 서버에게 도착하지 못한다면 서버는 클라이언트로부터 ACK를 받지 못하게 되고 재전송을 시도합니다.

하지만 클라이언트는 이미 종료된 상태이기 때문에 서버는 영원히 클라이언트로부터 ACK메시지를 받지 못하게 됩니다. 

(추측이지만, 일정기간 기다렸다가 재전송을 시도하게 되고 이미 종료된 클라이언트 소켓의 RST 패킷으로 인해 정리가 시도되지 않을까 합니다.)

 

하지만 클라이언트가 TIME_WAIT 상태에 놓여있었다면, ACK를 받지 못했다는 서버의 요청에 재전송을 할 수 있게 되고, 안전하게 종료할 수 있습니다.  (서버가 재전송을 요청할 때 TIME_WAIT 타이머는 재기동 됩니다.)

 

이러한 이유로 TIME_WAIT 상태를 사용하게 됩니다.

 

TIME_WAIT은 최대 세그먼트 생존 시간(MSL, maximum segment lifetime)의 2배와 같은 시간을 대기하기 때문에 2MSL 대기 상태라고도 부릅니다. RFC상으로는 MSL을 2분으로 정의하지만, 실제 구현은 30초, 1분, 2분 등 다양하고 얼마든지 수정할 수 있습니다.

제 로컬PC는 TIME_WAIT상태가 1분동안 지속됨을 확인했습니다. 

sysctl net.inet.tcp.fin_timeout
net.inet.tcp.fin_timeout: 60000

 

TIME_WAIT은 매우 중요하지만, 마냥 좋기만 한 상태는 아닙니다. 

위에 잠깐 이야기한 TIME_WAIT의 특성(종료를 시작한 소켓은 무조건 돌입, 요청을 받을 때마다 TIME_WAIT 타이머가 재가동 됨) 때문에 어느 쪽에서 종료를 시작할 것인지도 중요한 포인트가 됩니다.

그 키워드는 Active Close / Passive Close이고, 더 나아가서 SO_REUSEADDR 같은 옵션도 설정이 필요할 수 있습니다.

 

이 이야기는 다음 포스팅에 해보도록 하겠습니다.

 


궁금한게 있으면 댓글 남겨주세요 :)

728x90