TCP 프로토콜은 OSI 7 Layer 중 4계층인 전송 계층의 대표적인 프로토콜이다. TCP는 신뢰할 수 있고 정확한 데이터를 전달하기 위해 연결형 통신을 사용한다.
TCP는 3-way handshaking 과정을 통해 연결을 설정하고 4-way handshaking을 통해 해제한다.
3-way handshaking
- 클라이언트가 서버에 SYN 패킷을 전송한다. 이때 SYN 패킷을 보낸 클라이언트는 SYN/ACK 패킷을 기다리는 SYN_SENT 상태가 된다.
- 서버가 SYN 패킷을 받고 SYN_RCVD 상태가 되어 SYN/ACK 패킷을 보낸다. 이때 ACK Number는 클라이언트가 보낸 SYN 패킷의 Sequence Number에 1을 더한 수이다.
- 클라이언트가 SYN/ACK 패킷을 받고 ESTABLISHED 상태가 된다. 서버에 ACK 패킷을 보낸다. 이때 ACK Number는 위와 마찬가지로, 서버가 보낸 SYN 패킷의 Sequence Number에 1을 더한 수이다. ACK 패킷을 받은 서버도 ESTABLISHED 상태가 된다. 이후부터 상호 간에 데이터를 송수신한다.
4-way handshaking
- 서버와 클라이언트 모두 Established 상태에 있다. 클라이언트가 서버에 FIN 패킷을 보내고 FIN_WAIT_1 상태가 된다.
- FIN 패킷을 받은 서버는 ACK 패킷을 클라이언트에 보낸다. ACK Number는 FIN 패킷의 Sequence Number에 1을 더한 것이다. 서버는 CLOSED_WAIT 상태로 들어간다. ACK 패킷을 받은 클라이언트는 FIN_WAIT_2 상태가 된다. 이와 동시에 서버는 연결되어 있는 Application에 close() 요청을 보낸다.
이후 Application이 close() 될 준비가 되면, 서버는 클라이언트에 FIN 패킷을 보내고 LAST_ACK 상태가 된다.
- FIN 패킷을 받은 클라이언트는 TIME_WAIT 상태가 되고 ACK 패킷을 서버에 보낸다. ACK Number는 받은 FIN 패킷의 Sequence Number에 1을 더한 것이다. TIME_WAIT 상태에 들어간 클라이언트는 일정 시간 뒤 CLOSED 상태로 들어간다.
- ACK 패킷을 받은 서버는 CLOSED 상태가 된다.
- 클라이언트가 바로 CLOSED 상태가 되지 않고 TIME_WAIT 상태로 대기하는 이유?
서버에서 FIN 패킷을 보내기 전에 전송한 데이터가 라우팅 지연이나, 패킷 유실로 인한 재전송 등으로 FIN 패킷보다 늦게 도착한다면 해당 패킷은 유실될 위험이 있다. 이러한 현상에 대비하여 클라이언트는 FIN 패킷을 수신하더라도 일정 시간동안 세션을 남겨 놓고 잉여 패킷을 기다리게 된다.