![[네트워크] TCP 세션 종료, 4-way handshake](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbRN8X%2FbtsLLrqiXvn%2FgJncY2skIaSQoKQvko5ApK%2Fimg.png)
TCP/IP에서 두 호스트가 통신을 하기 위해서는 3-way handshake를 통해 TCP 세션을 맺어야 한다. 맺은 세션을 통해 데이터를 주고받기 때문에 TCP 프로토콜은 신뢰성 있는 프로토콜이라 부른다. 세션을 안전하게 종료하기 위해서는 각 호스트에 남아있는 모든 데이터를 전송한 후 연결을 종료해야 한다. 실제로 4-way handshake를 통해 남아있는 모든 데이터를 전송 후에 TCP 세션을 종료하게 된다.
TCP 4-way handshake
- 클라이언트 → 서버 FIN 세그먼트 전송
- 세션을 종료하기 위해 FIN 플래그를 1로 설정한 세그먼트를 전송한다.
- 서버의 FIN 세그먼트를 기다리는 FIN_WAIT 상태가 된다.
- 서버 → 클라이언트 ACK 세그먼트 전송
- 서버는 클라이언트로부터 FIN 세그먼트를 전송받았다는 의미의 ACK 세그먼트를 전송한다.
- ACK 세그먼트를 보낸 시점에 서버에서 아직 보낼 데이터가 남아 있을 수 있다.
- 서버 : CLOSE_WAIT 상태가 되어, 남아 있는 데이터를 모두 전송하기 위해 대기한다.
- 클라이언트 : FIN_WAIT 상태로 서버의 FIN 세그먼트를 기다린다.
- 서버 → 클라이언트 FIN 세그먼트 전송
- 서버에서 남아있는 데이터를 모두 전송한 경우, 세션을 종료할 수 있다는 FIN 세그먼트를 전송한다.
- 클라이언트로부터 ACK 세그먼트를 기다리는 LAST_ACK 상태가 된다.
- 클라이언트 → 서버 ACK 세그먼트 전송
- 클라이언트는 서버로부터 FIN 세그먼트를 전송받았다는 의미의 ACK 세그먼트를 전송한다.
- 클라이언트는 서버로부터 전송받지 못한 데이터가 있을 수도 있으므로 TIME_WAIT 상태로 대기한다.
- ACK 세그먼트를 전송받은 서버는 CLOSED 상태가 된다.
- 클라이언트는 2MSL만큼 지난 후 CLOSED 상태가 된다.
TIME_WAIT, CLOSE_WAIT
- TIME_WAIT : Active Close 쪽에서 ACK 세그먼트 유실 또는 네트워크 지연을 방지하기 위한 상태
- ex. 클라이언트(Active Close) → 서버(Passive Close)로 전송한 ACK 세그먼트가 네트워크 중간에서 유실될 수 있다.
- CLOSE_WAIT : Passive Close 쪽에서 남아있는 모든 데이터를 전송하기 위한 상태
Q1. 클라이언트가 서버로 ACK 세그먼트를 전송 후, CLOSED 상태로 되지 않는 이유?
클라이언트 → 서버로 ACK 세그먼트를 전송 후, 클라이언트는 TIME_WAIT 상태가 된다. TIME_WAIT 상태인 호스트는 TCP 연결이 되어있는 호스트로부터 데이터를 전송받을 수 있는 상태이다.
서버 → 클라이언트로 전송한 ACK 세그먼트가 네트워크 중간에 유실될 수 있다. 서버는 클라이언트로 전송한 FIN 세그먼트에 대한 응답이 돌아오지 않은 상태이므로, 서버 → 클라이언트로 FIN 세그먼트를 재전송하게 된다. 이처럼 네트워크 중간에 세그먼트가 유실될 수 있으므로, 클라이언트는 세션을 바로 종료하지 않고 TIME_WAIT 상태로 대기하는 것이다.
Q2. 세션을 연결할 때와 달리, 세션을 종료할 때는 4단계인 이유?
세션이 안전하게 종료되기 위해서는 호스트에 남아있는 데이터를 모두 전송해야 한다. 따라서 클라이언트가 연결 종료할 수 있는 상태라고 할지언정, 서버는 남아있는 데이터가 있을 수도 있으므로, 서버는 클라이언트의 FIN 세그먼트에 대한 ACK 세그먼트를 먼저 보낸 후에, 서버에 남아 있는 모든 데이터를 전송하는 과정을 거친다. 서버에 남아있는 모든 데이터를 전송하게 되면 서버 → 클라이언트로 FIN 세그먼트를 전송한다.
참고