목차
- TCP란?
- 3 way Handshake
- 4 way Handshake
- Questions
1. TCP란?
TCP는 전송 제어 프로토콜(Transmission Control Protocol)의 핵심 프로토콜 중 하나로, IP와 함께 TCP/IP라는 명칭으로도 널리 불립니다. TCP는 전송 계층에 위치하며, 네트워크의 정보 전달을 통제하는 프로토콜이자 인터넷을 이루는 핵심 프로토콜로써 정보를 안정적으로, 순서대로, 에러 없이 교환할 수 있게 합니다.
TCP는 연결형 서비스를 지원하는 프로토콜로 인터넷 환경에서 기본으로 사용합니다. TCP의 특징은 다음와 같습니다.
- 연결형 서비스로 연결이 성공해야 통신이 가능합니다.
- 3-way handshaking과정을 통해 연결을 설정하고 4-way handshaking을 통해 해제합니다
- 데이터의 전송 순서를 보장합니다. (패킷에 번호를 부여)
- 흐름 제어, 혼잡 제어, 오류제어
- 신뢰성 있는 데이터를 전송합니다.
- UDP보다 속도가 느립니다.
TCP는 연속성보다 신뢰성 있는 전송이 중요할 때에 사용하는 프로토콜로 파일 전송과 같은 경우에 사용됩니다.
UDP는 사용자 데이터그램 프로토콜(User Datagram Protocol)로써 인터넷 프로토콜 스위트의 주요 프로토콜 가운데 하나입니다. TCP와 함께 데이터그램으로 알려진 단문 메시지를 교환하기 위해서 사용됩니다. (TCP는 패킷, UDP는 데이터그램 단위로 처리)
UDP는 단순성, 낮은 신뢰성, 비연결성, 데이터그램 도착 순서가 바뀌거나 중복되거나, 누락되는 등의 특징을 가지며 일반적으로 오류의 검사와 수정이 필요 없는 애플리케이션에서 사용합니다.
2. 3 way Handshake
앞서 TCP는 정확한 전송을 보장해야 한다고 했습니다. 따라서 통신을 하기 전에 논리적인 접속을 성립하기 위해 TCP는 3 way handshake과정을 진행합니다. 3-way handshaking는 목적지와 수신지를 확실히 하여 정확한 전송을 보장하기 위해서 세션을 수립하는 과정을 의미합니다.
3 way handshake는 다음과 같은 과정으로 진행됩니다.
1. 클라이언트가 서버에게 SYN 패킷*을 보냄 (sequence : x)
2. 서버가 SYN(x)를 받고, 클라이언트로 받았다는 신호인 ACK와 SYN 패킷을 보냄 (sequence : y, ACK : x+1)
3. 클라이언트는 서버의 응답인 ACK(x+1)과 SYN(y) 패킷을 받고, ACK (y+1)를 서버로 보냄
SYN : Connection을 생성할 때 사용하는 flag
ACK : data를 전송하면 수신자가 받았음을 알려주기 위해 쓰는 flag (Client의 Sequence Number+1을 하여 ACK로 돌려줌)
FIN : Connection을 끊을 때 사용하는 flag
sequence number : TCP 세그먼트의 연속된 데이터 번호. 송신자가 최초로 데이터를 전송할 때 sequence number를 임의의 랜덤 숫자로 지정
3. 4 way Handshake
3-Way handshake가 TCP의 연결을 초기화 할 때 사용했다면, 4-Way handshake는 세션을 종료하기 위해 수행됩니다.
1. 클라이언트는 서버에게 연결을 종료한다는 FIN 플래그를 보냄
2. 서버는 FIN을 받고, 확인했다는 ACK를 클라이언트에게 보냄 (이때 남은 모든 데이터를 보내기 위해 CLOSE WAIT 상태가 됨)
3. 클라이언트는 FIN을 받고 확인했다는 ACK를 서버에게 보냄 (아직 서버로부터 받지 못한 데이터가 있을 수 있으므로 TIME_WAIT을 통해 기다림)
- 서버는 ACK를 받은 이후 소켓을 닫습니다.
- TIME_WAIT시간이 끝나면 클라이언트도 닫습니다.(Closed)
- TIME_WAIT 상태는 의도치 않은 에러로 인해 연결이 데드락으로 빠지는 것을 방지합니다. 만약 에러로 인해 종료가 지연되다가 타임이 초과되면 CLOSED로 들어갑니다.
4. Questions
Q. TCP의 연결 설정 과정(3단계)과 연결 종료 과정(4단계)이 단계가 차이나는 이유?
A. Client가 데이터 전송을 마쳤다고 하더라도 Server는 아직 보낼 데이터가 남아있을 수 있기 때문에 일단 FIN에 대한 ACK만 보내고, 데이터를 모두 전송한 후에 자신도 FIN 메시지를 보내기 때문입니다.
Q. 만약 Server에서 FIN 세그먼트를 전송하기 전에 전송한 패킷이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 인해 FIN 패킷보다 늦게 도착하는 상황이 발생하면 어떻게 될까?
A. Client에서 세션을 종료시킨 후 뒤늦게 도착하는 패킷이 있다면 이 패킷은 Drop되고 데이터는 유실될 것입니다.
이러한 현상에 대비하여 Client는 Server로부터 FIN을 수신하더라도 일정시간(디폴트 240초) 동안 세션을 남겨놓고 잉여 패킷을 기다리는 과정을 거치게 되는데 이 과정을 "TIME_WAIT" 라고 합니다.
Q. (4 way handshake) 클라이언트에서 FIN 패킷을 보내고, 서버에서 ACK 패킷을 보낸 후 FIN 패킷을 보낸 상황이라고 가정합시다. 이때 클라이언트에서 ACK패킷을 전송했는데, 서버에서 받지 못했다면 어떻게 될까요?
A. 두가지 경우가 있을 것 같습니다. 첫번쨰는 서버에서 ACK 패킷을 받지 못했다는 것을 클라이언트에 알려주어 다시 패킷을 보낼 줄 수 있을 것 같습니다.
그리고 두번째는 time wait 상태인 클라이언트가 일정 시간이 되어 종료되는 상황입니다. 그렇게 되면 서버는 ACK 패킷을 받지 못한채, 타임아웃으로 종료될 것 같습니다.
Q. 초기 Sequence Number인 ISN을 0부터 시작하지 않고 난수를 생성해서 설정하는 이유?
A. Connection을 맺을 때 사용하는 포트(Port)는 유한 범위 내에서 사용하고 시간이 지남에 따라 재사용됩니다. 따라서 두 통신 호스트가 과거에 사용된 포트 번호 쌍을 사용하는 가능성이 존재합니다. 서버 측에서는 패킷의 SYN을 보고 패킷을 구분하게 되는데 난수가 아닌 순처적인 Number가 전송된다면 이전의 Connection으로부터 오는 패킷으로 인식할 수 있습니다. 이런 문제가 발생할 가능성을 줄이기 위해서 난수로 ISN(Initail Sequence Number)을 설정합니다.
참고