Public/tip & tech

TCP Status

quantapia 2008. 6. 24. 10:21
TCP연결시에는 알다시피 3way handshaking을 한다. close시에는 client, server 가 각각 FIN을 보낸 후 ACK를 받는다(총 4번의 트랜젝션).

TCP연결에는 여러개의 상태가 있는데, netstat으로 확인할 수 있는 상태들에 대해 간단히 정리해보면,

  • 서버에서 listen()이 호출되면 상태는 LISTEN으로 바뀐다.
  • 이 때 client에서 SYN을 보낸 후 SYN_SENT로 상태가 바뀌면
  • 서버에서 이를 받고 SYN_RCVD로 바뀌고 SYN ACK를 보내준다.
  • 그리고 client에서 SYN을 다시 받게 되면 비로소 ESTABLISHED로 바뀐다.
  • 이 후 send(), recv()군의 함수들로 계속 통신을 하다가
  • client에서 close()호출로 인해 FIN 을 보내고 FIN_WAIT1상태가 되면
  • 서버에서 이를 받고 ACK를 보낸 후 CLOSE_WAIT으로 상태를 바꾸고
  • client에서는 이를 받으면 FIN_WAIT2로 바뀌게 된다.
  • client에서 close할 준비가 끝났으므로, 이제는 서버에서 close()가 호출되면 FIN이 전송되고, 상태는 LAST_ACK이 된다.
  • client에서는 ACK를 보낸 후 TIME_WAIT상태가 되고, Maximum Segment Lifetime x 2시간 정도 기다리다가 소켓을 닫는다.
  • 서버에서는 이 ACK를 받고 CLOSED로 상태가 바뀐다.

close시 일반적으로 client에서 먼저 FIN을 보내고(active close), 서버는 이를 받으면 recv()에 EOF가 전달된다. 서버는 자신이 보낸 FIN에 대한 ACK를 받아야 close된다(passive close).

TIME_WAIT이 필요한 이유 client에서 ACK를 보냈는데, 서버가 못받으면, 서버는 LAST_ACK상태에서 일정시간이 지나도 ACK가 안오므로 FIN을 다시 보낸다. 이때 client가 이미 close 한 상태이거나 같은 포트번호로 다른 접속을 시도하고 있다면 처리할 수 없으니까, TIME_WAIT을 두어 다시 들어온 FIN에 대해 ACK를 주는 것이다. (client에서는 그래서 재접속시 다른 포트 번호를 받게 된다).