핵심 인사이트 (3줄 요약)
- 본질: TCP(Transmission Control Protocol)는 밑바닥 IP의 멍청하고 무책임한 택배 배송을 못 미더워하여 4계층에 강림한 깐깐한 배송 반장으로, 패킷이 순서대로 도착했는지, 중간에 분실된 건 없는지 일일이 번호를 매기고(Sequence Number) 수신 확인(ACK)을 받아내는 지구상에서 가장 꼼꼼하고 신뢰성 높은 전송 프로토콜이다.
- 연결 지향형 (3-Way Handshake): 묻지도 따지지도 않고 데이터를 냅다 던지는 UDP와 달리, TCP는 통신을 시작하기 전에 "야, 나 데이터 보낼 건데 너 준비됐어? (SYN)" "응, 준비됐어. 넌? (SYN-ACK)" "나도 됐어! (ACK)"라며 서로 3번 악수를 굳게 맺어 안전한 논리적 터널(세션)을 파놓고 나서야 비로소 데이터를 밀어 넣는다.
- 바이트 스트림 기반 (Byte Stream): 택배를 상자(블록) 단위로 뚝뚝 끊어서 보내지 않고, 수도꼭지를 튼 것처럼 데이터를 **연속된 1바이트짜리 낱알들의 흐름(Stream)**으로 쪼르륵 흘려보낸다. 받는 쪽은 이 낱알들의 번호표를 보고 다시 예쁘게 조립한다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
-
개념: 전송 계층(Transport Layer)에서 종단 간(End-to-End) 신뢰성 있는 바이트 스트림(Byte Stream) 전송을 보장하는, 인터넷 프로토콜 슈트(TCP/IP)의 핵심 프로토콜 (RFC 793).
-
필요성: 내가 미국 구글 서버에 1GB짜리 영화를 다운받으려 한다. 인터넷망(IP)은 불안정해서 중간에 패킷 3개가 짤려 먹히고, 5번 패킷이 1번 패킷보다 먼저 도착하는 개판이 벌어진다. 만약 이걸 보정해 주지 않으면 내 노트북에 받아진 1GB짜리 영화 파일은 깨져서 재생조차 안 된다. **"야! 데이터 하나 보낼 때마다 번호표 딱딱 붙여! 그리고 못 받은 번호 있으면 구글한테 다시 보내라고(재전송) 화내! 그리고 순서 섞여 오면 1, 2, 3, 4번 순서대로 다시 맞춰서 합체해!!"**라는 완벽한 뒷수습(신뢰성) 시스템이 절대적으로 필요했다.
-
💡 비유:
- UDP (우편엽서): 엽서 100장을 써서 우체통에 냅다 넣습니다. 친구가 몇 장을 잃어버렸는지, 어떤 엽서가 먼저 도착했는지 나는 알 바 없습니다. 빠르지만 무책임합니다.
- TCP (우체국 등기 소포): 100쪽짜리 책을 한 장 한 장 뜯어서 번호표를 붙여 보냅니다. 친구는 1쪽을 받으면 "나 1쪽 받았어! 2쪽 줘!"라고 문자를 보냅니다. 만약 "7쪽 받았어!"가 와야 하는데 안 오면, 내가 7쪽을 잽싸게 복사해서 다시 보냅니다. 조금 느리고 번거롭지만, 친구의 책이 100% 완벽하게 조립됨을 보장합니다.
📢 섹션 요약 비유: TCP는 택배가 파손될까 봐 뽁뽁이를 10겹으로 감싸고, 배송 기사에게 반드시 **"수취인 친필 서명(ACK)을 받아오라"**고 시키는 편집증 걸린 배달 시스템입니다. 비용(헤더 오버헤드)과 시간(지연)은 들지만, 중요한 서류(웹, 메일, 파일)를 보낼 때 이보다 완벽할 순 없습니다.
Ⅱ. TCP의 4대 철학과 뚱뚱한 헤더 구조 (Deep Dive)
1. TCP를 관통하는 4가지 키워드 (실무/시험 필수)
- 연결 지향형 (Connection-Oriented): 통신 전에 반드시 3-Way Handshake로 세션을 연다.
- 신뢰성 보장 (Reliability): Sequence Number(번호표)와 Acknowledgment(수신 확인, ACK) 번호를 교환하여 중간에 유실된 데이터를 귀신같이 잡아내어 재전송(Retransmission)한다.
- 흐름 제어 (Flow Control): 내 컴퓨터 램(RAM)이 100MB 찼는데 구글이 1GB를 쏴버리면 터진다. 내 컴퓨터가 구글에게 "야, 나 지금 10MB밖에 못 받으니까 천천히 좀 보내!(Window Size 조절)"라며 멱살을 잡고 속도를 낮춘다.
- 혼잡 제어 (Congestion Control): 너와 나 사이의 문제가 아니라 인터넷(KT) 망 자체가 막혀서 데이터가 증발할 때, TCP 스스로 "앗! 톨게이트 막힌다!" 눈치채고 자발적으로 송신 속도를 확 줄여버리는 선진 시민 의식(Slow Start, Congestion Avoidance)을 발휘한다.
2. 무거운 TCP 헤더 (최소 20바이트 ~ 60바이트)
저 4가지 깐깐한 짓을 다 하려다 보니 TCP 헤더 안에는 온갖 기능의 스위치와 도장들이 빼곡하게 박혀 있다.
- 출발지/목적지 포트 (16비트씩): 다중화를 위한 포트 번호.
- Sequence Number (32비트): 내가 보내는 데이터의 첫 번째 바이트 순서 번호. "이거 1,000번 조각이야!"
- Acknowledgment Number (32비트): 상대방에게 "나 1,000번까지 잘 받았어. 이제 1,001번 보낼 차례야!"라고 요구하는 징표.
- Header Length (4비트): 헤더가 워낙 가변적(옵션이 붙음)이라, 헤더가 어디까지인지 알려주는 구분선.
- Window Size (16비트): 내 컴퓨터가 한 번에 소화할 수 있는 남은 램(버퍼) 공간. 흐름 제어의 핵심.
- Checksum (16비트): 가다가 데이터 찌그러졌는지 검사하는 도장.
3. TCP의 핵심 제어 플래그 (6 Control Flags)
TCP 헤더 안에는 6개의 전등(비트)이 스위치처럼 달려 있어, 불이 켜지냐 꺼지냐에 따라 패킷의 성격이 180도 달라진다.
- SYN (Synchronize): 통신을 시작하자며 악수를 청할 때 켜는 불. (접속 요청)
- ACK (Acknowledgment): 네 말 잘 들었다고 끄덕일 때 켜는 불. (수신 확인)
- FIN (Finish): 우리 그만 헤어지자며 정중하게 이별을 통보할 때 켜는 불. (연결 정상 종료)
- RST (Reset): 대판 싸우고 "야 닥쳐! 다 끊어!!"라며 강제로 선을 쥐어뜯어 버릴 때 켜는 불. (강제 연결 리셋, 비정상 종료)
- PSH (Push): 버퍼에 데이터 쌓일 때까지 기다리지 말고 지금 있는 거 당장 화면에 쏴주라는 급행 불.
- URG (Urgent): 이거 폭탄 해체 암호니까 순서 무시하고 제일 먼저 처리해!! 라는 응급 불.
┌─────────────────────────────────────────────────────────────┐
│ TCP 바이트 스트림(Byte Stream)의 쪼개기 마법 │
├─────────────────────────────────────────────────────────────┤
│ │
│ [ 구글 서버 ] ── 10MB짜리 압축 파일 전송 준비! │
│ │
│ TCP 왈: "야! MTU가 1500이니까, 1460 바이트(MSS)씩 톱으로 썰어!" │
│ │
│ 1번 조각: [ TCP 헤더 (Seq: 1) ] [ 데이터 1460 바이트 ] ──▶ 슝! │
│ 2번 조각: [ TCP 헤더 (Seq: 1461) ] [ 데이터 1460 바이트 ] ──▶ 슝!│
│ 3번 조각: [ TCP 헤더 (Seq: 2921) ] [ 데이터 1460 바이트 ] ──▶ 슝!│
│ │
│ * 내 PC의 조립: "오, 1번 다음에 1461번 왔고... 2921번 오면, │
│ 이 번호표(Seq) 순서대로 본드로 다시 붙이면 │
│ 10MB짜리 원본 100% 복구 완료네!" │
└─────────────────────────────────────────────────────────────┘
📢 섹션 요약 비유: TCP의 제어 플래그들은 야구 경기의 **"포수 사인"**과 같습니다. 투수(송신자)가 함부로 공을 던지지 못하게, 포수(수신자)가 손가락으로 SYN(시작), ACK(잘 받음), FIN(그만 던져) 사인을 끊임없이 주고받으며 완벽한 호흡으로 경기를 이끌어갑니다.