[네트워크] TCP 3 & 4 way handshake

xoey·2024년 11월 13일

네트워크

목록 보기
2/10
post-thumbnail

1. Prerequisite

TCP의 3 & 4 Way Handshake에 대해 알아보기 전에, 우선 아래의 내용을 살펴보자.

1.1. Transport Layer

OSI 7계층에서 Transport Layer에는 양 끝단(End to End)의 사용자들이 신뢰성 있는 데이터를 주고 받을 수 있도록 해주어, 상위 계층들이 데이터 전달의 유효성이나 효율성을 생각하지 않도록 해준다.

전송 계층은 인터넷의 기반인 TCP/IP 모델과 일반적인 네트워크 모델인 개방형 시스템 간 상호 접속(Open Systems Interconnection, OSI) 모두 포함하고 있다.

전송 프로토콜 중 잘 알려진 것이 바로 TCP와 UDP이다.

  • Transport Layer: Application 프로세스들 간의 논리적인 통신을 제공한다. 즉, 서로 다른 컴퓨터에서 실행되는 애플리케이션 프로세스들이 데이터를 주고받을 수 있도록 지원한다.
  • Network Layer: 호스트 간의 논리적인 통신을 제공한다. 네트워크 계층은 패킷을 목적지까지 전송하는 역할을 하며, 이를 위해 IP 주소를 사용해 데이터를 올바른 경로로 전달한다. 네트워크 계층은 각 호스트(컴퓨터 또는 장치) 간의 통신 경로를 결정하고, 패킷이 목적지까지 도달할 수 있도록 라우팅을 처리한다.

1.2. TCP & UDP

TCP에서는 Transport Layer에서 주고 받는 데이터 단위를 세그먼트(Segment)라고 한다. 반면, UDP에서는 데이터를 데이터그램(Datagram)이라고 부른다. 데이터그램은 비연결형 서비스에서 사용되는 용어로, UDP가 데이터를 패킷으로 처리하는 방식을 설명하는 데 사용된다.

🙋🏻‍♀️ 왜 굳이 두 단어를 구분해야 하죠?

TCP는 연결 지향적이며, 데이터의 ‘정확한 전송’을 보장하기 위한 여러 제어 기능이 포함되어 있다. 이러한 특징을 반영하기 위해 각 세그먼트에는 데이터 외에도 제어 정보가 포함된다.

반면 데이터그램은 독립적이고 신뢰성 없이 전송되는 데이터 단위를 가리킨다. 이때문에 데이터그램에는 데이터 전송을 간단하고 빠르게 처리하기 위해 필수적인 최소한의 제어 정보만 포함시킨다.

즉, TCP와 UDP 모두 패킷에 정보가 담긴다는 점은 동일하지만, 헤더의 구조와 내용이 다르기 때문에 다른 단어를 사용하는 것이다.

1.2.1. TCP(Transmission Control Protocol)

TCP는 인터넷 상에서 데이터를 안전하게 전달하기 위해 IP와 함께 사용하는 프로토콜이다. TCP는 다음과 같은 특징을 가지고 있다.

  • 연결지향적(Connected-Oriented): 데이터를 보내기 전에 3-Way Handshake를 통해 연결을 설정하고, 이후 데이터를 주고받는다. 데이터를 주고받는 동안에도 지속적으로 연결 상태를 유지하며, 데이터 전송이 끝난 후에는 4-Way Handshake를 통해 연결을 종료한다.
  • 신뢰성 보장: TCP는 데이터를 신뢰성 있게 전송하는 것을 보장한다. 데이터가 손실되거나 손상되면 재전송하고, 데이터가 올바른 순서로 도착하도록 관리한다. 수신된 데이터의 확인(ACK) 응답을 통해 데이터 전송이 제대로 이루어졌는지 확인한다.
  • 흐름 제어(Flow Control): 송신자와 수신자가 서로 다른 속도로 데이터를 처리할 수 있는 상황을 대비하여, 송신자가 데이터를 너무 빠르게 보내는 것을 방지한다. 이를 통해 수신자의 버퍼가 넘치지 않도록 조절한다.
  • 혼잡 제어(Congestion Control): 네트워크의 혼잡 상태를 감지하고, 데이터 전송 속도를 동적으로 조절하여 네트워크 트래픽을 관리한다. 이를 통해 네트워크 혼잡 시 성능 저하를 방지한다.
  • 속도: TCP는 여러 보조 기능을 통해 신뢰성을 보장하기 때문에 UDP보다 속도가 느릴 수 있다. 하지만 이 속도 차이는 매우 미세하기 때문에 대부분의 사용자가 체감하기 어렵다.
  • 파일 전송, 웹 브라우징, 이메일, 데이터베이스 통신 등 신뢰성이 중요한 상황에서 주로 사용된다.

1.2.2. UDP(User Datagram Protocol)

UDP는 비연결형 프로토콜로, 데이터 전송 전에 연결을 설정하지 않고 빠르게 데이터를 전송하는 데 중점을 둔다. UDP는 다음과 같은 특징을 가지고 있다.

  • 비연결형(Connectionless): UDP는 데이터를 전송하기 전에 연결 설정을 하지 않으며, 데이터를 송신하면 수신자가 받는지 여부를 확인하지 않는다. 이는 TCP의 3-Way Handshake와 같은 과정이 없다는 것을 의미한다.
  • 독립적인 패킷 전송: 각 패킷은 독립적으로 전송되며, 서로 다른 경로로 전송될 수 있다. 따라서 UDP는 데이터의 순서 보장을 하지 않으며, 손실된 패킷에 대한 재전송도 이루어지지 않는다.
  • 빠른 전송 속도: UDP는 연결 설정 및 확인 과정이 없기 때문에 빠른 전송 속도를 제공한다. 또한, 흐름 제어와 혼잡 제어가 없어 네트워크 부하가 적다.
  • 스트리밍, 실시간 비디오/음성 통화, 온라인 게임 등 연속성이 중요하고 약간의 데이터 손실이 큰 문제가 되지 않는 경우에 주로 사용된다.

TCP와 UDP는 각각 별도의 포트 주소 공간을 관리하므로, 같은 포트 번호를 사용해도 서로 독립적인 포트로 동작한다.

또한 클라이언트 프로그램이 동시에 여러 서버와 연결을 맺을 때, 같은 프로토콜을 사용하는 경우라도 각 연결마다 다른 포트 번호를 사용하여 여러 연결을 처리한다.

프로토콜 종류TCPUDP
연결 방식연결형 서비스비연결형 서비스
패킷 교환 방식가상 회선 방식데이터그램 방식
전송 순서전송 순서 보장전송 순서가 바뀔 수 있음
수신 여부 확인확인 o확인 x
통신 방식1:1 통신1:1 or 1:N or N:N
신뢰성높다낮다
속도느리다빠르다

1.3. 포트(Port) 상태 정보

  • CLOSED: 포트가 닫혀 있는 상태로, 어떤 연결 요청도 받지 않는다.
  • LISTEN: 서버의 포트가 열린 상태로 연결 요청을 기다리는 상태이다. 이때 서버는 클라이언트로부터 들어오는 연결 요청을 받을 준비가 된 상태이다.
  • SYN_RCV: 서버가 클라이언트의 SYN 요청을 받고, 이에 대한 응답으로 SYN-ACK 패킷을 보낸 상태이다. 즉, 서버는 클라이언트로부터 받은 연결 요청에 대해 응답을 보내고, 연결이 완료되기를 기다리고 있다.
  • ESTABLISHED: 클라이언트와 서버 간에 연결이 성립된 상태. 이 상태에서는 데이터를 주고받을 수 있으며, 연결이 정상적으로 작동하고 있는 상태이다.

1.4. 플래그 정보

TCP 헤더에는 6개의 CONTROL BIT(플래그 비트)가 있으며, 각 비트는 특정 기능을 수행하는 패킷임을 나타낸다. 플래그 비트는 1bit의 정보를 가지며, 1이면 해당 기능을 수행하는 패킷이다.

📌 Sequence Number

TCP에서는 각 패킷이 전송될 때마다 Sequence Number(시퀀스 번호)가 부여된다. 이 번호는 패킷이 전송된 순서를 나타내고, 데이터가 손실 없이, 정확한 순서로 도착하도록 관리된다.

1.4.1. SYN(Synchronize Sequence Number) / 000010

  • SYN 플래그는 연결 설정에 사용된다. 클라이언트가 서버에 연결 요청을 보낼 때 사용되며, 초기 Sequence Number를 설정하여 세션을 시작한다.
  • 주로 3-Way Handshake의 첫 번째 단계에서 사용되며, 클라이언트와 서버 간에 초기 연결을 설정하는 역할을 한다.

1.4.2. ACK(Acknowledgement) / 010000

  • ACK 플래그는 응답 확인을 나타낸다. 클라이언트나 서버가 패킷을 정상적으로 수신했음을 확인하고, 이에 대한 응답을 보낼 때 사용된다.
  • ACK Number 필드는 수신자가 다음에 받고자 하는 데이터의 Sequence Number를 의미한다.
    • e.g. 클라이언트 → 서버로 Sequence Number가 1000인 데이터 패킷을 보낸다.
    • 서버가 이 패킷을 받으면, “Sequence Number 1000에서 시작하는 데이터를 잘 받았다.”는 의미로 ACK Number를 1001로 설정하여 클라이언트에게 응답한다.
    • ACK Number 1001은 “이제 1001번부터 시작하는 데이터를 보내달라”는 의미이다.
    • 클라이언트는 ACK Number를 보고, 그다음 데이터를 1001번 시퀀스 번호부터 전송한다.
  • 연결이 설정된 후 모든 패킷에 이 ACK 플래그가 설정된다. 데이터 전송 과정에서 거의 모든 패킷에 사용된다고 볼 수 있다.

1.4.3. FIN(Finish) / 000001

  • FIN 플래그는 연결을 종료할 때 사용된다. 더 이상 전송할 데이터가 없다는 것을 알리기 위해 클라이언트 또는 서버가 FIN 패킷을 전송한다.
  • 주로 4-Way Handshake 과정에서 연결 종료 요청을 나타내며, 양측 모두 이 플래그를 사용하여 연결을 종료한다.

2. 3-Way Handshake

3-Way Handshake는 TCP 연결을 설정하는 과정으로, 클라이언트와 서버가 데이터를 주고받기 전에 신뢰성 있는 연결을 설정하는 데 사용된다. 이 과정은 양방향 통신이 가능하도록 준비하기 위해 수행되며, 다음 세 단계로 이루어진다.

2.1. 클라이언트 → 서버 : SYN

  • 클라이언트가 서버에 SYN 패킷을 보내 연결을 요청한다.
  • 이때 SYN 플래그가 설정된 패킷이 전송되며, 이 패킷에는 랜덤한 초기 Sequence Number가 포함되어 있다.
  • 클라이언트는 서버에게 “너랑 연결을 맺고 싶다”라는 의사를 전한다.
  • 이 상태에서 서버는 LISTEN 상태에 있을 수 있다. 즉, 서버는 클라이언트와의 연결 요청에 귀기울이고 있는 상태이다.

2.2. 서버 → 클라이언트 : SYN-ACK

  • 서버는 클라이언트의 연결 요청을 수락하고, SYN-ACK 패킷을 클라이언트로 보낸다.
  • 서버는 클라이언트가 보낸 SYN 패킷을 확인하고, 자신도 연결할 준비가 되었음을 나타내기 위해 SYN 플래그와 함께 ACK 플래그를 설정한 패킷을 보낸다.
  • ACK Number는 클라이언트가 보낸 Sequence Number + 1이다. 이는 클라이언트가 보낸 요청을 받았음을 확인하는 숫자이다.
  • 이 시점에서 서버는 SYN_RCV 상태이다.

2.3. 클라이언트 → 서버 : ACK

  • 클라이언트는 서버가 보낸 SYN-ACK 패킷을 받으면, 다시 서버에게 ACK 패킷을 보낸다.
  • 이때 ACK 플래그만 설정된 패킷을 보내며, 이는 연결이 성립되었음을 확인하는 응답이다.
  • 클라이언트와 서버가 모두 ESTABLISHED 상태로 전환되며, 이제 양측은 데이터를 주고받을 준비가 완료된 상태이다.

이 3단계 과정을 통해 양방향에서 데이터를 전송할 준비가 완료된 Full-duplex 통신이 형성된다. Full-duplex 통신은 양방향으로 동시에 데이터를 전송할 수 있는 상태를 의미한다.

3. 4-Way Handshake

4-Way Handshake는 TCP 연결을 종료하는 절차로, 클라이언트와 서버가 각각의 데이터 전송이 끝났음을 명확히 확인하는 과정을 거친다. 이때 양쪽 모두 FIN 플래그를 사용해 더 이상 보낼 데이터가 없음을 알리고, 마지막으로 ACK 패킷을 주고받아 연결을 종료한다.

3.1. 클라이언트 → 서버 : FIN(+ACK)

  • 클라이언트가 더 이상 보낼 데이터가 없을 때, 연결을 종료하려고 FIN 플래그가 설정된 패킷을 서버에 보낸다.
  • 이때 클라이언트는 FIN_WAIT_1 상태로 들어가며, 서버로부터 ACK 응답을 기다린다.
  • 여기서 중요한 점은, FIN 패킷은 데이터를 보내는 일방적인 요청이지만, 연결 자체를 완전히 종료하지는 않는다. 아직 서버가 데이터를 전송할 수도 있기 때문이다.

3.2. 서버 → 클라이언트 : ACK

  • 서버는 클라이언트가 보낸 FIN 패킷을 받으면, 확인 응답(ACK 패킷)을 클라이언트에 보낸다.
  • 서버는 CLOSE_WAIT 상태로 전환되며, 아직 처리 중인 데이터가 있다면 이를 처리하고 나서 연결을 완전히 종료할 준비를 한다.
  • 클라이언트는 서버로부터 ACK 패킷을 받으면 FIN_WAIT_2 상태로 전환되며, 서버가 종료할 때까지 기다린다.

3.3. 서버 → 클라이언트 : FIN

  • 서버가 남은 데이터를 모두 전송하고 나면, 연결을 종료하기 위해 FIN 패킷을 클라이언트에게 보낸다.
  • 서버는 이때 LAST_ACK 상태로 들어가며, 클라이언트로부터 최종 ACK를 받기 전까지 기다린다.

3.4. 클라이언트 → 서버 : ACK

  • 클라이언트는 서버로부터 FIN 패킷을 받은 후, 마지막 ACK 패킷을 서버에 보내 서버의 종료 요청을 확인한다.
  • 클라이언트는 이때 TIME_WAIT 상태로 돌아가며, 네트워크 상에 남아있을지 모르는 패킷(e.g. 마지막 ACK 패킷이 손실된 경우)을 처리하기 위해 일정 시간 대기한다.
  • 서버는 클라이언트로부터 ACK를 받으면 완전히 연결을 종료하고 CLOSED 상태로 전환된다.

⏱️ TIME_WAIT 상태

  • 클라이언트는 TIME_WAIT 상태에서 남아있을 수 있는 잘못된 패킷을 처리하기 위해 잠시 대기한다. 네트워크에 혹여나 남아있을 수 있는 지연된 패킷을 처리하고, 만약 서버가 FIN 패킷을 다시 보내는 경우를 처리하기 위함이다.
  • TIME_WAIT 시간이 끝나면 클라이언트도 CLOSED 상태로 전환되고, 연결이 완전히 종료된다.

🔎 Termination 종류

  • Graceful Connection Release(정상적인 연결 해제)
    • 양쪽 모두가 연결을 안전하게 닫기 위해 서로 FIN과 ACK를 주고받으며 연결을 종료하는 방식이다. 4-Way Handshake가 바로 이 정상적인 연결 해제에 해당된다.
    • 양쪽이 서로 연결 종료를 동의하며, 모든 데이터 전송이 끝날 때까지 연결을 유지한다.
  • Abrupt Connection Release(갑작스러운 연결 해제)
    • 갑자기 한쪽이 연결을 강제로 종료하는 방식이다.
    • 이때는 RST(Reset) 세그먼트를 사용해 연결을 즉시 끊는다.
    • e.g. 비정상적인 상황(리소스 부족, 비정상적인 패킷 수신 등)에서 한쪽이 연결을 강제로 닫고 싶을 때 RST 패킷을 보내 연결을 종료한다.

🔎 Half-Close 기법

Half-Close는 한쪽에서 먼저 연결을 닫았지만, 다른 쪽은 계속해서 데이터를 전송할 수 있는 상태를 말한다.

  • 예를 들어 클라이언트가 먼저 FIN 패킷을 보내면서 자신의 데이터를 모두 보냈음을 알리지만, 서버는 남은 데이터를 전송할 수 있는 상태를 유지한다.
  • FIN 패킷에 ACK가 포함되어 있는 이유는 “일단 데이터를 보내는 건 끝났지만, 서버가 보낼 데이터는 계속 받을 준비가 되어있다.”는 의미이다.
  • 서버가 데이터를 모두 전송하고 나면, 다시 FIN 패킷을 보내 연결을 완전히 종료한다.

Reference

profile
[Roman 8:18] consider that our present sufferings are not worth comparing with the glory that will be revealed in us.

0개의 댓글