오늘은 소켓의 종료와 그에 따라 발생하는 소켓의 상태 변화에 대해 알아 보도록 하겠다.

 먼저 소켓은 생성될 때는 3-way hand shaking을 통해서 생성되지만, 종료 될때는 한단계 더 많은 4-way hand shaking을 거쳐 종료 된다.

four way handshake

four way handshake


  위에서 분명히 4-way.. 4단계라고 이야기 했다. 그럼 어떤 4단계를 거치는지 알아 보자.

  1. A가 B에게 연결 종료를 요청한다.
  2. B는 바로 종료를 하는 것이 아니라, 단순히 ACK만을 날리고 있다. B도 종료 하기 전에 할
     일이 있기 때문에 바로 FIN을 날리지 않고, 단순히 ACK를 날리고 CLOSE_WAIT 상태로 넘어
     간다.
 3. 볼일을 다 보고난 B는 이제서야 FIN을 날리고 연결을 종료 하고자 한다.
 4. A는 B의 FIN을 잘 받았다는ACK를 B에게 보내게 되고, A의 ACK를 받으면 B는 종료한다.

 4의 과정에서 A는 ACK를 날리고 난후 소켓이 제거될때 까지 TIME_WAIT상태에 있게 되며 이 시간은 대략 30 초 정도지만 시스템 마다 다르다.
 TIME_WAIT에 있는 동안에는 커널이 주소와 port를 바인딩 하고 있기때문에 재사용 할 수가 없다. 게다가 TIME_WAIT에 있는 주소와 port를 재사용 요청을 하면 TIME_WAIT 시간을 더욱 늘릴 뿐이다.
 
 그렇다면 이렇게 불편한 TIME_WAIT를 왜 사용해야만 하는가??
 만일 A가 B로 보낸 마지막 종료 메시지(SEQ:5001,ACK:6002) 이후 바로 종료 했다고 가정하자. 그런데 라우터의 문제라던지 기타등등의 네트워크 상에서 발생하는 어떠한 원인에 의해 마지막 종료 메시지가 B에 도착하지 않게되었다.
 이때쯤 되면 B는 종료하지 못하고(TCP는 소심해서 뭘 하던지 완료 메시지를 받아야 마음을 놓는다) 다시 A에게 한번 더 FIN(SEQ:6001, ACK:5001)을 날린다.
 여기서 A가 TIME_WAIT가 아니라 바로 종료 되어버린 상태 였다면, 이 마지막 FIN 역시 무시했을 테고 B는 여전히 A가 종료 되었는지 살아 있는지 모르고 아둥바둥거리고 있게 될 것이다. 하지만 TIME_WAIT에 있는 A의 소켓은 여전히 주소와 포트를 바인딩 하고 있는 상태이기 때문에 다시 날아 오는 B의 FIN을 감지하고 다시한번 마지막 ACK를 날려 줄 수 있는 것이다.

참 고 :
 열혈강의 TCP/IP 소켓 프로그래밍 : 윤성우
 Unix Network Programming : Stevens

관련 글 :  
 TIME_WAIT state vs SO_REUSEADDR option -> http://kukuta.tistory.com/17

'진리는어디에' 카테고리의 다른 글

sendto & recvfrom  (0) 2007.03.23
half-close  (0) 2007.03.20
소켓 종료와 TIME_WAIT(Socket termination and TIME_WAIT)  (10) 2007.03.19
Read/Write lock  (8) 2007.03.18
libevent and multithread  (6) 2007.03.06
extern  (0) 2007.02.23
Posted by kukuta
TAG

댓글을 달아 주세요

  1. kang1 2007.08.28 00:53 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요? 올리신글 잘읽어보았습니다. 내용이 매우 좋네요,
    헌데 한가지 궁금한게 있는데 time_wait시간동안 해당 Port를 bind하려했을때
    time_wait시간이 늘어난다라고 했는데, 그럼 다른말로 그시간동안에 bind시도가계속된다면 영영 그 Port는 사용이 불가능할수도 있다는 말인가요??

    • Favicon of http://kukuta.tistory.com BlogIcon kukuta 2007.08.28 08:06 신고  댓글주소  수정/삭제

      네..
      TIME_WAIT에 있는 소켓에 계속적으로 bind 시도를 하면 할때 마다 TIME_WAIT로 빠져드는 것으로 알고 있습니다.

      한 가지 사례로, 제가 간단한 에코 서버를 만들면서 바인드 에러가 났고, 계속적으로 시도를 하자 에러 상태가 계속 되더군요. 하지만 최초에 에러가 나고 일정 시간 후에 다시 시도를 하면 정상적으로 접속이 되었구요.

      실험하는 것이 아니라 오류 상황인지라 정확한 시간을 테스트 해보지는 않았지만 지속적으로 연결을 시도했던 시간이 아무것도 하지 않고 기다린 시간보다 더 길었던 것으로 기억됩니다.

      혹시 이 내용에 이의가 있으신 분의 악플/태클 환영합니다.

      감사합니다.

  2. 이지연 2009.05.25 19:23 신고  댓글주소  수정/삭제  댓글쓰기

    퍼갈게요

  3. Favicon of http://passman.tistory.com BlogIcon 패스맨 2011.05.17 10:45 신고  댓글주소  수정/삭제  댓글쓰기

    좋은글 감사해요~저도 퍼갈게요~

  4. rednoeul 2011.09.06 15:16 신고  댓글주소  수정/삭제  댓글쓰기

    좀 퍼가겠습니다.
    감사합니다.^^

  5. 곰탱곰탱 2014.10.20 22:30 신고  댓글주소  수정/삭제  댓글쓰기

    내용 감사합니다. 담아갈께요오~



티스토리 툴바