TCP
✒️ 2025-05-31 23:02 내용 수정
참고 자료 : NordVPN TCP UDP 차이: 두 프로토콜 비교
TCP(Transmission Control Protocol)
참고 자료 : 위키백과 전송 제어 프로토콜, wikipedia TCP, mdn web docs TCP
두 장치 간의 데이터를 순서대로 교환하게 하는 프로토콜
- TCP는 인터넷 프로토콜 스위트(TCP/IP 모델)에서 전송 계층에 위치한다.
- 네트워크 참고.
- 데이터와 패킷이 보내진 순서대로 전달하는 것을 보장한다.
- UDP와 같이 인터넷에서 데이터를 전송할 때 사용하는 프로토콜이다.
TCP 세그먼트
- TCP 패킷은 정확한 표현이 아니며, TCP 세그먼트가 TCP 프로토콜 데이터 유닛을 의미하는 정확한 표현이다.
- 패킷(Packet)은 TCP/IP 모델 인터넷 계층에서 사용하는 데이터 단위다.
- 네트워크 PDU 참고.
TCP 세그먼트 생성
- 데이터 스트림으로부터 데이터를 받아들여 청크 단위로 분할한다.
- 분할된 청크에 TCP Header를 붙여 TCP 세그먼트를 만든다.
- TCP 세그먼트를 IP 데이터그램에 패킷화하여 상대방과 주고받는다.
세그먼트 구조
- TCP 세그먼트는 세그먼트 헤더와 데이터 두 부분으로 나뉜다.
- TCP 헤더 : 송신 포트, 수신 포트 등 데이터 전송과 관련된 메타 데이터
- 데이터 : 응용 계층에서 생성한 전송할 데이터
| 헤더 | 설명 |
|---|---|
| 출발지와 목적지 포트 번호 | |
| 순서 번호 (Sequence Number) |
데이터의 순서와 재조립을 위한 번호 |
| 확인 응답 번호 (Acknowledgment Number) |
패킷 수신 확인에 사용되는 일련번호 |
| 데이터 오프셋 | TCP 헤더 크기 |
| 플래그 | TCP 연결 설정, 종료, 데이터 전송 상태 등을 나타내는 플래그 정보 |
| 창 크기(Window size) | 패킷을 받을 수 있는 창의 크기 |
| 체크섬(Checksum) | 오류 검출을 위한 체크섬 |
| 긴급 포인터 | 긴급 데이터 바이트를 가리키는 포인터 |
| 기타 옵션 |
TCP의 동작
참고 자료 : mdn web docs TCP 핸드셰이크, Geeksforgeeks TCP 3-Way Handshake Process, Geeksforgeeks Why TCP Connect Termination Nedd 4-Way-Handshake, wikipedia TCP Protocol operation
-
TCP 연결은 통신을 위한 엔드포인트를 나타내는 리소스인 Network Socket를 통해 운영 시스템에 의해 관리된다.
- Network Socket(Internet Socket) : 컴퓨터 네트워크의 Network Node 내에 있는 소프트웨어 구조로, 노드 내의 작동 중인 애플리케이션의 프로세스 유지 동안에만 생성된다.
- Network Node : 통신 네트워크 내의 데이터를 주고 받는 상호작용 엔드포인트나 재분배 지점
- 참고 자료 : wikipedia Network Socket, wikipedia Node(networking)
-
TCP Socket 상태
- TCP 연결의 생명 주기 동안 각 로컬 엔드 포인트는 여러 단계의 상태 변화를 거친다.
| 상태 | 엔드포인트 | 설명 |
|---|---|---|
| LISTEN | 서버 | 서버가 연결 요청을 기다리는 상태 |
| SYN-SENT | 클라이언트 | 클라이언트가 연결 요청(SYN)을 보낸 후 응답을 기다리는 상태 |
| SYN-RECEIVED | 서버 | 서버가 SYN을 수신하고, SYN-ACK를 보낸 후 ACK를 기다리는 상태 |
| ESTABLISHED | 서버 클라이언트 |
연결이 성립되어 데이터 전송이 가능한 상태 |
| FIN-WAIT-1 | 서버 클라이언트 |
연결 종료를 위해 FIN을 보낸 후 ACK 또는 FIN을 기다리는 상태 |
| FIN-WAIT-2 | 서버 클라이언트 |
FIN에 대한 ACK를 받은 후, 상대방의 FIN을 기다리는 상태 |
| CLOSE-WAIT | 서버 클라이언트 |
상대방의 FIN을 수신하고, 애플리케이션의 종료 요청을 기다리는 상태 |
| CLOSING | 서버 클라이언트 |
양측이 동시에 FIN을 전송하고 상대방의 ACK를 기다리는 상태 |
| LAST-ACK | 서버 클라이언트 |
이전 연결 종료 요청에 대한 ACK와 연결 종료 요청 FIN을 보낸 후 상대방의 ACK를 기다리는 상태 마지막으로 상대의 ACK를 기다리는 상태 |
| TIME-WAIT | 서버 클라이언트 |
마지막 ACK를 보낸 후, 지연된 패킷이 네트워크를 떠날 때까지 기다리는 상태. |
| CLOSED | 서버 클라이언트 |
연결이 존재하지 않는 상태 |
- TCP 동작은 3단계로 나눌 수 있다.
- 연결 생성 : 클라이언트와 서버의 연결 설정
- 데이터 전송 : 클라이언트와 서버 간의 데이터 교환
- 연결 종료 : 클라이언트와 서버의 연결 종료
1. 연결 생성
- 클라이언트가 서버에 연결 시도를 하기 전에 서버는 연결에 사용할 포트에 바인딩하고, 해당 포트에서 연결 요청을 수신 대기해야 한다.
- 위 과정을 passive open이라고 한다.
- passive open이 완료되면 클라이언트는 active open을 3-Way Handshake를 통해 시작하여 서버와의 연결을 시작할 수 있다.
TCP 3-Way Handshake
- TCP/IP 네트워크의 두 장치 간의 신뢰할 수 있는 연결을 설정하는 방법이다.
- 3-Way Handshake, SYN-SYN-ACK로도 부른다.
-
SYN(Synchronize) : 클라이언트가 서버로 SYN을 전송하면서 active open이 수행된다.
- 클라이언트는 세그먼트 전송 시 임의의 초기 순서 번호(ex: A)를 설정한다.
-
SYN-ACK(SYN-Acknowledgment) : 이에 대한 응답으로 서버는 SYN-ACK를 클라이언트로 전송한다.
- Acknowledgment 숫자는 수신했던 세그먼트 초기 순서 번호에 1을 더한 값(ex: A+1)으로 설정한다.
- 서버는 패킷의 순서 번호를 또 다른 임의의 값(ex: B)으로 설정하여 전송한다.
-
ACK(Acknowledgment) : 클라이언트는 서버로 ACK를 보낸다.
- 순서 번호는 서버에서 수신한 Acknowledgment 숫자(ex: A+1)로 설정한다.
- 클라이언트는 서버에 전송할 Acknowledgment 숫자를 서버의 패킷 순서 번호에 1을 더한 값(ex: B+1)으로 설정한다.

- 이 과정을 통해 서버와 클라이언트는 서로의 순서 번호를 확인하고, 신뢰할 수 있는 전이중 통신(full-duplex communication)을 시작한다.
2. 데이터 전송
- TCP는 데이터 전송 시 다양한 핵심 기능을 제공한다.
1) 순서가 보장된 전송
- TCP는 순서 번호(Sequence Number)를 사용하여 데이터의 각 바이트를 식별할 수 있다.
- 이를 사용하여 전송한 데이터의 순서를 식별할 수 있어 데이터를 수신하는 측에서 순서 번호를 사용하여 데이터를 올바른 순서로 재조립할 수 있다.
- Acknowledgment Number(확인 응답 번호)를 사용하여 데이터가 특정 바이트까지 수신 되었음을 알릴 수 있다.
- 애플리케이션에 데이터가 전달되었음을 의미하진 않는다.
2) 데이터 손실 확인 및 재전송
- 데이터 전송 시 데이터 손실을 감지하면 전송자는 데이터를 다시 보낸다.
-
재전송 타임아웃(RTO)
- 송신자가 데이터를 보낸 후, ACK 도착 시간을 확인하는 타이머를 가동하여 데이터의 손실 여부를 확인한다.
- ACK를 받지 못한 경우에만 작동하기 때문에 패킷 재정렬이나 지연으로 인한 오탐지 가능성이 있다.
-
중복 누적 ACK
- 세그먼트가 손실되면 세그먼트의 번호를 확인할 수 없다.
- 수신자는 누적 ACK 방식을 사용하기 때문에 세그먼트들의 번호를 누적으로 확인하며, 손실된 세그먼트 이후의 패킷을 확인할 수 없다.
- 따라서 이후의 데이터 패킷을 수신하더라도 수신하지 못한 세그먼에 대한 ACK를 계속 보낸다.
- 중복으로 누적된 확인 응답은 패킷 손실의 신호로 보고, 송신자가 수신자로부터 3번의 중복된 ACK를 확인하면 손실된 패킷을 다시 전송한다.
-
시간 기반 손실 감지(RACK)
- RTO와는 다른 시간 기반 알고리즘으로, 패킷의 전송 시간과 ACK 수신 시간을 비교하여 손실 여부를 판단한다.
- 참고 자료 : RACK: a time-based fast loss detection algorithm for TCP
3. 연결 종료
- 연결 종료 시엔 4-Way Handshake를 사용하여 양측의 연결을 독립적으로 종료한다.
- 3-Way Handshake 방식으로도 연결을 종료할 수 있다.
- 호스트 A가 FIN을 전송하고, 호스트 B가 FIN와 ACK를 합친 응답을 전송하고, 호스트 A가 ACK를 보내는 방식으로 한다.
- 하지만 TCP는 전이중 통신(full-duplex communication)을 지원하기에 양측이 독립적으로 데이터를 전송할 수 있어 한 쪽에서 종료 요청을 보내더라도 다른 쪽에서 데이터를 전송할 수도 있다.
- 이 경우는 half-open 상태로, 한 쪽은 연결을 종료하여 데이터를 더 이상 보낼 수 없지만, 다른 쪽은 데이터를 계속해서 전송할 수 있다.
- 따라서 각 방향의 데이터 전송을 독립적으로 종료할 필요가 있어 이를 구분하기 위한 FIN과 ACK 세그먼트가 필요하다.
TCP 4-Way Handshake
- 두 장치 간의 연결을 종료할 때 사용하는 방법이다.
- 각 TCP 엔드 포인트의 FIN와 ACK 세그먼트 쌍 교환으로 이루어진다.
-
FIN(종료 요청) : 클라이언트에서 FIN 패킷을 전송한다.
- active close로 FIN을 전송한 후
FIN_WAIT_1상태이다.
- active close로 FIN을 전송한 후
-
ACK(확인 응답) : 서버에선 ACK 패킷으로 확인 응답을 보낸다.
- 서버는 클라이언트로부터 종료 요청을 수신하더라도 데이터를 독립적으로 더 전송할 수도 있다.
- passive close로
CLOSE_WAIT상태이다. - 클라이언트는 ACK를 수신 후
FIN_WAIT_2상태가 된다.
-
FIN(종료 요청) : 서버에서 통신이 종료되면 FIN 패킷을 전송한다.
- 데이터 전송이 모두 완료된 후에 FIN 요청을 보낸다.
- 따라서 2번 ACK와 상태가 다르기 때문에 ACK와 FIN을 동시에 보내는 것은 위험하다.
- 서버는
LAST_ACK상태이며, 클라이언트는 FIN 수신 후TIME_WAIT상태가 된다.
- 데이터 전송이 모두 완료된 후에 FIN 요청을 보낸다.
-
ACK(확인 응답) : 클라이언트는 ACK 패킷을 전송하여 통신을 마무리한다.
- 서버는 ACK 수신 후
CLOSED상태가 되며, 클라이언트도CLOSED상태가 된다.
- 서버는 ACK 수신 후
