본문 바로가기
Programming/Socket

Socket을 닫은 뒤 바로 쓸 수 없는 이유

by whitele 2021. 5. 4.
반응형

socket 관련 예제를 진해하다 보면 연결을 끊고 바로 같은 PORT를 이용하는 경우가 잦을 것이다. 그럴 때마다 소켓이 정상적으로 동작하지 않는다. 이것은 TCP 특성상의 이유로 정상적인 현상이다. TCP의 특성에 의한 시스템적으로 막혀 있는 것이다.

TCP이해

 TCP에서는 신뢰성, 단편화등 많은 기능을 수행하기 위해 3-way handshaking 3.3/4 연결 종료를 수행한다. 결과적으로는 신뢰성있는 통신을 하기 위해서 이 기법을 사용한다. TCP에서는 세션 관리를 한다. 이는 신뢰성 있는 연결 상태를 확립하기 위해 존재하는 TCP의 특성이다. 이로 인해 반대로 취약점이 있기도 하나 신뢰성있는 통신을 하기 위한 기능이다. 주제처럼 세션을 끊을 때 이 현상이 발생한다.

TCP 연결 종료 동작

위와 같이 먼저 FIN을 요청한 쪽에서 먼저 TIME_WAIT 상태가 된다. 이 때문에 반쪽짜리 연결 종료라고도 한다. 이 TIME_WAIT때문에 바로 소켓을 이용할 수 없는 이유이다. 이것이 존재하는 이유는 혹시모를 처리할 패킷이 도착할 것을 대비하여 소켓을 열어두는 것이다.

커널 및 응용프로그램

먼저 응용 프로그램은 close()함수를 호출하고 연결종료를 수행한다. 응용프로그램이 종료되었음에도 불구하고 커널에서는 이 TCP 소켓의 time_wait 상태가 종료될 때 까지 소켓을 대기시킨다. 그 후 지정된 time_wait 시간이 지나면 소켓이 Closed 상태가 되면서 소켓이 닫히게 된다. 이때 비로소 같은 포트로 소켓을 열 수 있게된다.

 

응용프로그램이 이미 종료 되었어도 커널에서는 소켓을 완전히 닫지 않는다. 이 때 다시 바로 실행한다면 아직 소켓이 살아 있기에 응용프로그램이 정상적으로 실행되지 않는다. 소켓이 PORT를 점유하고 있어서 바로 쓸 수가 없는 것이다. 이를 해결할 방법이 3가지로 들 수 있다.

  • 응용프로그램의 port 주소를 변경한다.
  • time_wait 시간을 변경한다.
  • 종료될 때까지 기다린다.

2,3번은 크게 추천하지 않는다. port 주소를 변경하는 것이 가장 바람직하다.

728x90
반응형

댓글