본문 바로가기

Network

TCP 3 way handshake & 4 way handshake

TCP

TCP 는 Connection을 맺고 연속적으로 패킷의 상태를 확인 / 유지하는 Connection Oriented Protocol이다. 이에, 커넥션을 수립/해제하는 과정을 이해하는 것이 중요하다. 커넥션을 수립하는 과정은 3-way handshake, 커넥션을 해제하는 과정은 4-way handshake이다. 자세한 과정은 아래와 같다.

3-way handshake

TCP 3-way handshake

TCP 연결을 수립하는 과정이다. 양쪽 모두 데이터를 송/수신할 준비가 되었다는 것을 보장한다. 

 

1) Client는 Server에게 접속 요청 패킷(SYN)을 전송하고, SYN_SENT상태가 된다. 이 때, 임의의 Sequence Number를 담아 전송한다. 

2) Server는 요청을 수락할 때, Client에게서 받은 난수에 1을 더한 값을 Acknowledge Number로 설정하고, SYNACK flag bit를 set한 세그먼트를 전송한다. 이후 Server는 SYN_RECEIVED 상태가 된다. 

3) Client는 Server에게 2에서 받은 난수에 1을 더한 값을 실은 ACK를 보내고, ESTABLISHED 상태가 된다. 서버가 해당 요청을 받으면, 서버도 ESTABLISHED 상태가 된다. 

 

SYN 단계에서 난수를 보내는 이유는, 서버가 클라이언트 측의 요청을 제대로 받았는지, 그리고 반대로 클라이언트가 서버의 요청을 제대로 받았는지 확인하기 위한 용도이다. 

4-way handshake

TCP 4-way handshake

TCP 세션을 해제하기 위한 과정이다. 

 

1) Client가 연결을 해제하겠다는 FIN 플래그를 전송한다. 이 때 Client의 상대는 FIN_WAIT_1 상태이다. 

2) Server는 확인의 의미인 ACK를 보내고, 자신의 통신이 끝날 때까지 기다린다. (CLOSE_WAIT 상태) ACK를 받은 Client는 FIN_WAIT_2 상태로 변경된다. 

3) Server의 통신이 끝나면, Client에게 FIN을 전송하고, LAST_ACK 상태가 된다.

4) Client는 확인의 의미로 ACK를 보내고 TIME_WAIT상태가 되며, Server는 ACK 패킷을 수신 후 CLOSED 상태가 된다. Client는 2MSL(Maximum Segment Life)만큼의 시간이 지난 후 CLOSED가 된다. 

 

이 때, 4에서 Client가 바로 세션을 닫지 않고 2MSL만큼 기다리는 이유가 무엇일까?

Client쪽에서 Server에서 FIN을 받자마자 세션을 닫아버리면, 네트워크 지연 등의 이유로 FIN 이전에 전송한 패킷이 FIN 이후에 도착하게 되는 경우, 그 패킷은 Drop되고, 결론적으로 데이터는 유실된다. 이러한 상황을 방지하기 위해, Client는 Server에서 FIN을 수신하더라도 일정 시간(2 MSL = default: 240s)동안 세션을 남겨두고 패킷을 기다리는 과정을 거친다. MSL 값은 아래와 같은 커맨드로 확인할 수 있다.

$ sysctl net.inet.tcp | grep msl
net.inet.tcp.msl: 15000

 

References

1) mindnet.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-22%ED%8E%B8-TCP-3-WayHandshake-4-WayHandshake

 

[ 네트워크 쉽게 이해하기 22편 ] TCP 3 Way-Handshake & 4 Way-Handshake

우선  TCP의 3-way Handshaking 에 대하여 알아보겠습니다. * TCP 3-way Handshake 란? TCP는 장치들 사이에 논리적인 접속을 성립(establish)하기 위하여 three-way handshake를 사용한다. TCP 3 Way Handshake..

mindnet.tistory.com

2) evan-moon.github.io/2019/11/17/tcp-handshake/