https://github.com/WeareSoft/tech-interview 의 내용을 기반으로 작성하였습니다.
TCP의 3-Way Handshake 와 4-Way Handshake에 대해 알아보기 전에, 우선 아래의 내용에 대해 알아보겠다.
OSI 7 레이어에서 Transport Layer에는 양 끝단(End to end)의 사용자들이 신뢰성있는 데이터를 주고 받을 수 있도록 해 주어, 상위 계층들이 데이터 전달의 유효성이나 효율성을 생각하지 않도록 해준다. 전송 계층은 인터넷의 기반인 TCP/IP 참조 모델과 일반적인 네트워크 모델인 개방형 시스템 간 상호 접속 (Open Systems Interconnection, OSI) 모두 포함하고 있다.
전송 프로토콜 중 잘 알려진 것이 바로 TCP와 UDP이다.
Application 프로세스
들 간의 논리적인 통신
을 제공host
간의 논리적인 통신
을 제공세그먼트
"라고 한다.데이터그램
"이라고 하기도 한다.인터넷상에서 데이터를 메세지의 형태로 보내기 위해 IP와 함께 사용하는 프로토콜
TCP는 애플리케이션에게 신뢰적이고 연결지향성 서비스를 제공한다. 일반적으로 TCP와 IP는 함께 사용되며 IP는 배달을, TCP는 패킷
의 추적 및 관리를 하게 됩니다.
TCP는 연결형 서비스로, 신뢰적인 전송을 보장하기에 hanshaking하고 데이터의 흐름제어와 혼잡제어를 수행합니다. 하지만 이러한 기능으로 인해 TCP의 속도는 느립니다.
TCP 특징
데이터를 데이터그램 단위로 처리하는 프로토콜 (데이터그램이란 독립
적인 관계를 지니는 패킷이라는 뜻 이다.)
UDP는 비연결형 프로토콜이다. 즉, 할당되는 논리적인 경로가 없고 각각의 패킷이 다른 경로로 전송되고 이 각각의 패킷은 독립적인 관계를 지니게 되는데, 이렇게 데이터를 서로 다른 경로로 독립 처리하는 프로토콜을 UDP 라고 합니다.
UDP는 연결을 설정하고 해제하는 과정이 존재하지 않는다. 서로 다른 경로로 독립적으로 처리함에도 패킷에 순서를 부여하여 재조립하거나 흐름제어 및 혼잡제어를 수행하지 않아 속도가 빠르며 네트워크 부하가 적다는 장점이 있지만 데이터 전송의 신뢰성이 낮다. 연속성이 중요한 실시간 서비스(스트리밍)에 좋다.
UDP 특징
3-Way Handshake 는 TCP의 접속,4-Way Handshake는 TCP의 접속 해제 과정이다.
TCP 통신은 PAR (Positive Acknowledgement with Re-transmission) 을 통해 신뢰적인 통신을 제공한다.
PAR을 사용하는 기기는 ack을 받을 때까지 데이터 유닛을 재전송한다!
수신자가 데이터 유닛(세그먼트)이 손상된것을 확인하면(Error Detection에 사용되는 transport layer의 checksum
을 활용), 해당 세그먼트를 없앤다. 그러면 sender는 positive ack이 오지 않은 데이터 유닛을 다시 보내야한다.
⇒ 이 과정에서 클라이언트와 서버 사이에서 3개의 Segment가 교환되는 것을 확인할 수 있다. 이것이 바로 3-way handshake의 기본 매커니즘이다.
Client의 Sequence Number+1
을 하여 ACK로 돌려줍니다.Step 1 (SYN)
클라이언트는 서버와 커넥션을 연결하기 위해 SYN을 보낸다. (seq : x)
CLOSED
- SYN_SENT
로 변함LISTEN
Step 2 (SYN + ACK)
서버가 SYN(x)을 받고, 클라이언트로 받았다는 신호인 ACK와 SYN 패킷을 보냄 (seq : y, ACK : x + 1)
Seq=y, Ack=x+1, SYN, ACK
)CLOSED
SYN_RCV
Step 3 (ACK)
클라이언트는 서버의 응답은 ACK(x+1)와 SYN(y) 패킷을 받고, ACK(y+1)를 서버로 보냄
ESTABLISED
SYN_RCV
⇒ ACK ⇒ ESTABLISED
⇒ 이를 통해 full-duplex 통신이 구축됩니다.
4-Way Handshake은 연결을 해제 (Connecntion Termination)하는 과정이다. 여기서는 FIN 플래그를 이용한다.
FIN
(finish) : 세션을 종료시키는데 사용되며, 더 이상 보낸 데이터가 없음을 나타낸다.TCP는 대부분의 connection-oriented 프로토콜과 같은 두 가지 연결 해제 방식이 있습니다.
Graceful connection release(정상적인 연결 해제)
정상적인 연결 해제에서는 양쪽이 커넥션이 서로 모두 커넥션을 닫을 때까지 연결되어 있다.
Abrupt connection release(갑작스런 연결 해제)
RST(TCP reset)
세그먼트가 전송되면 갑작스러운 연결 해제가 수행되는데, RST 세그먼트는 다음과 같은 경우에 전송된다.
연결 종료 요청 역시, 일반적으로 생각하는 우리가 일반적으로 생각하는 Client와 Server는 모두 서로 연결 요청을 먼저 할 수 있기 때문에, 연결 요청을 먼저 시도한 요청자를 Client로, 연결 요청을 받은 수신자를 Server쪽으로 생각하면 된다.
Half-Close 기법
아래 그림에서 처음 보내는 종료 요청인 (1) FIN 패킷에 실질적으로 ACK가 포함되어 있는 것을 알 수 있는데, 이는Half-Close 기법 을 사용하기 때문이다.
- 즉, 연결을 종료하려고 할 때 완전히 종료하지 않고
반만 종료
합니다.- Half-Close 기법을 사용하면 종료 요청자가 처음 보내는 FIN 패킷에 승인 번호를 함께 담아서 보내게 되는데, 이때 승인 번호의 의미는 "일단 연결은 종료할건데 귀는 열어둘게. 이 승인 번호까지 처리했으니까 더 보낼 거 있으면 보내" 가 됩니다.
- 이후 수신자가 남은 데이터를 모두 보내고 나면 다시 요청자에게 FIN 패킷을 보냄으로써 모든 데이터가 처리되었다는 신호 (3) FIN를 보냅니다. 그럼 요청자는 그때 나머지 반을 닫으면서 좀 더 안전하게 연결을 종료할 수 있게 됩니다.
STEP1 (Client → Server : FIN(+ACK)
FIN
플래그를 보낸다.STEP2 (Server → Client : ACK)
ACK
를 클라이언트에게 보내고 자신의 통신이 끝날때까지 기다린다. (이상태가 TIME_WAIT 상태)CLOSE_WAIT
상태에 들어갑니다. 그리고아직 남은 데이터가 있다면 마저 전송을 마친 후에 close( )를 호출FIN_WAIT_2
)STEP3 (Server → Client : FIN)
FIN
패킷을 클라이언트에게 보낸 후에, 승인 번호를 보내줄 때까지 기다니는 LAST_ACK
상태로 들어간다.STEP4 (Client → Server : ACK)
ACK
를 서버에게 보낸다.TIME_WAI
T을 통해 기다린다. (실질적인 종료과정 CLOSED
에 들어가게 된다.)TIME_WAIT
상태는 의도치 않은 에러로 인해 연결이 데드락으로 빠지는 것을 방지CLOSED
로 들어갑니다.서버는 ACK를 받은 이후 소켓을 닫는다 (Closed)
TIME_WAIT 시간이 끝나면 클라이언트도 닫는다 (Closed)
Q. TCP의 연결 설정 과정(3단계)과 연결 종료 과정(4단계)이 단계가 차이나는 이유?
A. Client가 데이터 전송을 마쳤다고 하더라도 Server는 아직 보낼 데이터가 남아있을 수 있기 때문에 일단 FIN에 대한 ACK만 보내고, 데이터를 모두 전송한 후에 자신도 FIN 메시지를 보내기 때문이다.
관련 Reference
Q. 만약 Server에서 FIN 플래그를 전송하기 전에 전송한 패킷이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 인해 FIN 패킷보다 늦게 도착하는 상황이 발생하면 어떻게 될까?
A. 이러한 현상에 대비하여 Client는 Server로부터 FIN 플래그를 수신하더라도 일정시간(Default: 240sec)동안 세션을 남겨 놓고 잉여 패킷을 기다리는 과정을 거친다. (TIME_WAIT 과정)
관련 Reference
Q. 초기 Sequence Number인 ISN을 0부터 시작하지 않고 난수를 생성해서 설정하는 이유?
A. Connection을 맺을 때 사용하는 포트(Port)는 유한 범위 내에서 사용하고 시간이 지남에 따라 재사용된다. 따라서 두 통신 호스트가 과거에 사용된 포트 번호 쌍을 사용하는 가능성이 존재한다. 서버 측에서는 패킷의 SYN을 보고 패킷을 구분하게 되는데 난수가 아닌 순처적인 Number가 전송된다면 이전의 Connection으로부터 오는 패킷으로 인식할 수 있다. 이런 문제가 발생할 가능성을 줄이기 위해서 난수로 ISN을 설정한다.
관련 Reference
TCP/UDP
Handshake
4way step2 close_wait 상태아닌가요?