[ ]go back, selective tcp ack의미 < 2손실이면, 1받고
[ ]arq 6,7슬라이드 설명햇엇던가
[ ]아 그래서 ack계산할떄, 데이터 크기는 거의 없는거라고 계산하는건가, 시험문제에서 < 왜 왕복인지에 대하여
[핵심 요약] 인터넷 트랜스포트 레이어 & 응용 계층
1. 트랜스포트 레이어 프로토콜 개요
- 종류: TCP, UDP, SCTP (SCTP는 윈도우 미지원으로 거의 안 씀).
- UDP: 멀티플렉싱 외에는 하는 일이 거의 없음. 권장되지 않음.
- TCP: 대부분의 응용 프로그램이 선택.
- 기능: 멀티플렉싱, 신뢰성 있는 전송(Error Control), 흐름 제어(Flow Control), 혼잡 제어(Congestion Control).
- 이 3가지 제어를 '윈도우(Window)'라는 프레임워크 안에서 통합적으로 수행.
2. TCP 헤더와 연결 설정/해제
- 헤더 분석:
- Source/Dest Port: 멀티플렉싱용.
- Sequence/Ack Number: 에러 컨트롤(ARQ)용.
- Receive Window: 흐름 제어용.
- 연결 설정 (Connection Setup):
- 3-Way Handshake: (SYN -> SYN/ACK -> ACK) 총 3번의 패킷 교환.
- 한계: 두 호스트가 완벽하게 100% 합의(연결 성립 확신)에 이르는 방법은 이론적으로 없음(두 장군 문제). 하지만 TCP에서는 대충 합의하고, 문제 생기면 RST(Reset) 플래그로 복구함.
- ISN (Initial Sequence Number): 첫 시퀀스 넘버는 보안을 위해 랜덤하게 설정하고 서로 교환함.
- 연결 해제: 보통 4-way (FIN -> ACK, FIN -> ACK) 방식.
3. TCP의 데이터 전송 특징 (Data Transfer)
- 스트림(Stream) 방식:
- 데이터를 **바이트(Byte)의 흐름(물)**처럼 취급. 경계가 없음.
- 재전송 시 처음에 보낸 패킷 크기와 다르게 잘라서 보낼 수도 있음.
- 이를 **세그먼트(Segment)**라고 부름.
- 시퀀스 넘버(Sequence Number) 규칙:
- 패킷의 번호가 아니라, 해당 패킷의 첫 번째 바이트 번호.
- (예시) Seq 92 (8바이트 데이터) -> 다음 패킷은 Seq 100 (92+8).
- ACK (Acknowledgment) 규칙:
- 누적 ACK (Cumulative ACK): "여기까지 다 잘 받았다"는 뜻.
- (예시) ACK 100의 의미: "99번까지 다 잘 받았고, 이제 100번부터 받을 차례다."
- 중간에 ACK 하나가 유실되어도, 다음 ACK가 잘 도착하면 앞의 내용도 확인된 것으로 간주(장점).
4. TCP의 3가지 땜빵(Patch) 알고리즘
TCP의 효율성을 위해 추가된 알고리즘들입니다.
- Delayed ACK (수신자): ACK를 바로 보내지 않고 잠시 기다렸다가, 보낼 데이터와 합치거나 다음 ACK와 합쳐서 보냄 (패킷 수 감소).
- Nagle's Algorithm (송신자): 데이터를 바로 보내지 않고 모아서 보냄. (헤더 오버헤드 감소).
- 단점: 반응속도가 중요한 CLI(명령어 입력) 환경에서는 답답해서 끄기도 함.
- Fast Retransmit (빠른 재전송): (중요/필수)
- 타이머가 터질 때까지 기다리면 너무 느림.
- 중복된 ACK (Duplicate ACK)가 3개 도착하면, 해당 패킷이 손실되었다고 판단하고 즉시 재전송.
5. TCP 타이머와 RTT (Retransmission Timeout)
- 문제: 네트워크 상태(RTT: 왕복시간)는 계속 변함. 타이머를 얼마로 설정할지가 관건.
- RTT 계산: '지수 이동 평균(Exponential Moving Average)' 사용.
- New_RTT = (0.875 * Old_RTT) + (0.125 * Current_RTT) (과거 비중 높게, 현재 비중 낮게).
- 타이머 설정 값: 평균 RTT + (4 * 표준편차).
- 매우 보수적이고 넉넉하게 잡음 (정규분포 가정 시 4배수 밖은 거의 확률 0).
- 그래서 타이머에만 의존하면 재전송이 너무 느려짐 -> Fast Retransmit이 필요한 이유.
6. 흐름 제어 (Flow Control)
- 목적: 수신자의 **버퍼(Receive Buffer)**가 넘치지 않게 조절.
- 동작: 수신자가 자신의 남은 버퍼 크기(Receive Window, rwnd)를 헤더에 실어 송신자에게 계속 알려줌. 송신자는 이 크기만큼만 데이터를 보냄.
7. 혼잡 제어 (Congestion Control) - 가장 중요한 부분
- 목적: 네트워크가 감당할 수 있는 수준으로 전송 속도 조절.
- 방식: Congestion Window (cwnd) 크기를 조절하여 간접적으로 속도 제어.
- 전송 속도 ≈ cwnd / RTT
- 알고리즘 진행 과정 (Jacobson의 AIMD):
- Slow Start (슬로우 스타트):
- 처음엔 1개(MSS)로 시작.
- RTT마다 2배씩 지수적으로 증가 (1, 2, 4, 8...).
- ssthresh (임계값)에 도달하면 종료.
- Congestion Avoidance (혼잡 회피):
- 임계값 도달 후에는 선형적(1씩)으로 증가. (조심스럽게 탐색).
- 손실 감지 시 (Loss Event):
- TCP Tahoe (초기 버전): 무조건 1로 초기화하고 다시 Slow Start. (너무 비효율적).
- TCP Reno (개선 버전):
- **타이머 종료(Timeout)**로 인한 손실: 심각한 혼잡. -> cwnd를 1로 줄임.
- 3 Duplicate ACK로 인한 손실: 가벼운 손실. -> **cwnd를 절반(1/2)**으로 줄이고 그 지점부터 선형 증가 (Fast Recovery).
- Slow Start (슬로우 스타트):
- TCP Cubic: 최신(리눅스/윈도우 기본). 3차 함수() 곡선을 사용하여, 줄어든 지점 근처에서는 천천히, 멀어지면 빠르게 윈도우 크기를 조절.
- y=x3y=x^3
8. 응용 계층 (Application Layer)
- 구조 (Architecture):
- Client-Server:
- 서버(제공자)와 클라이언트(사용자)가 명확.
- 서버 주소만 알면 됨(편리).
- 서버에 트래픽이 몰리는 단점, 확장성 한계.
- P2P (Peer-to-Peer):
- 모두가 서버이자 클라이언트(동료, Peer).
- 확장성이 좋음(사용자가 늘면 서버 역할도 늠).
- 상대방 찾기가 어렵고 관리가 힘듦. 불법 공유에 주로 사용.
- Client-Server:
- 요구사항 vs 현실:
- 응용 프로그램마다 요구사항(손실 민감, 속도, 보안 등)이 다름.
- 하지만 TCP(인터넷)가 해주는 건 오직 '신뢰성(손실 없음)' 하나뿐.
- 그럼에도 잘 돌아가는 이유? -> 현재 인터넷망이 자원 과잉(Over-provisioning) 상태라서 성능이 잘 나와주는 것뿐임 (ATM 망은 망했음).
1. "3가지 제어를 '윈도우(Window)'라는 프레임워크 안에서 통합적으로 수행한다"는 말의 뜻
여기서 **'프레임워크(Framework)'**라는 단어 때문에 헷갈리셨을 텐데, 거창한 소프트웨어 프레임워크(Spring, Django 등)를 말하는 게 아닙니다.
여기서는 "하나의 공통된 도구(구조)" 또는 **"하나의 방식"**이라고 이해하시면 됩니다. 즉, TCP는 '윈도우(Window)'라는 하나의 도구를 가지고 에러 제어, 흐름 제어, 혼잡 제어를 다 해결한다는 뜻입니다.
왜 '윈도우'가 핵심 도구일까요?
TCP에서 '윈도우'는 **"상대방의 확인(ACK) 없이 한 번에 보낼 수 있는 데이터의 양(버퍼의 크기)"**을 의미합니다. 이 '윈도우 크기'를 조절하는 것만으로 3가지 일을 다 합니다.
- 에러 제어 (Error Control):
- 윈도우 안에 있는 데이터를 보냈는데, ACK(확인)가 안 오면? -> 윈도우 안의 데이터를 재전송합니다. (이게 ARQ입니다.)
- 흐름 제어 (Flow Control):
- 수신자가 "나 배불러(버퍼 꽉 찼어)"라고 하면? -> 송신자는 윈도우 크기를 줄여서 보내는 양을 조절합니다. (상대방 상태에 맞춤)
- 혼잡 제어 (Congestion Control):
- 네트워크가 막히는 것 같으면? -> 송신자가 알아서 윈도우 크기를 확 줄입니다. (길 막히니까 조금만 보냄)
[요약]
- 따로따로 노는 게 아니라, **'윈도우 크기(보낼 양)'를 늘렸다 줄였다 하는 하나의 방식(프레임워크)**으로 **재전송(에러), 속도조절(흐름/혼잡)**을 한꺼번에 처리한다는 뜻입니다.
2. "연결 설정(Connection Setup)이 없어도 멀티플렉싱이 되나?"
결론부터 말씀드리면: 네, 됩니다. (UDP가 대표적입니다.)
질문하신 **'소켓'**이 여기서 핵심 정답입니다. 멀티플렉싱을 위해 필요한 건 '연결(악수)'이 아니라 **'번호표(포트 번호)'**이기 때문입니다.
원리 설명
- 소켓(Socket)과 바인딩:
- 프로그램(카카오톡, 브라우저 등)이 실행될 때 운영체제한테 소켓을 하나 만듭니다.
- 이때 **"나는 포트 번호 80번을 쓸게"**라고 찜합니다. (이걸 Binding이라고 합니다.)
- 운영체제는 장부에 적어둡니다. 80번 포트 = 브라우저, 5000번 포트 = 카카오톡
- 패킷 도착 (멀티플렉싱):
- 외부에서 패킷이 날아옵니다. (연결을 맺었든 안 맺었든 상관없음)
- 패킷 헤더에는 **목적지 포트 번호(Destination Port)**가 적혀 있습니다.
- 운영체제는 그냥 그 번호만 봅니다. "어? 포트 5000번이네? 장부 보니 카카오톡이네? 카카오톡한테 던져주자."
왜 연결 설정이 필요 없나요?
- **연결 설정(3-way handshake)**은 "우리 서로 대화할 준비 됐지? 순서 번호는 몇 번부터 할까?"라고 약속하는 과정입니다.
- 멀티플렉싱은 그냥 우체부가 우편함 번호(포트 번호) 보고 편지 꽂아주는 것과 같습니다.
- 우체부(OS)가 집주인(프로그램)이랑 미리 인사(연결 설정)를 안 해도, 우편함 번호(포트)만 정확하면 편지를 꽂아줄(분배) 수 있죠?
- 이게 바로 UDP가 연결 설정 없이도 멀티플렉싱이 가능한 이유입니다.
[시험용 요약]
- 멀티플렉싱의 핵심은 **헤더에 있는 포트 번호(Port Number)**와 운영체제의 소켓(Socket) 매핑이다.
- 연결 설정(Handshake)은 신뢰성을 위한 약속일 뿐, 포트 번호를 보고 데이터를 나누어주는(멀티플렉싱) 기능과는 별개다. 따라서 연결 설정이 없는 UDP도 헤더의 포트 번호 덕분에 멀티플렉싱이 가능하다.
'프레임워크(Framework)'는 IT 분야뿐만 아니라 사회 전반에서 정말 많이 쓰이는 단어라 헷갈리기 쉽습니다.
핵심 이미지는 **"뼈대(Frame) + 작업(Work)"**입니다. 즉, **"무언가를 하기 위해 미리 만들어진 뼈대나 규칙의 집합"**을 뜻합니다.
질문하신 내용에 맞춰 1. 강의에서의 의미, 2. 개발자들 사이에서의 의미, 3. 일반적인 의미로 나누어 딱 정리해 드릴게요.
1. 강의(TCP)에서의 의미: "통합 시스템" 또는 "메커니즘"
교수님이 "윈도우라는 프레임워크 안에서..."라고 하신 것은 **"윈도우(Window)라는 하나의 시스템(구조)을 이용해 여러 문제를 해결한다"**는 뜻입니다.
- 비유: '신용카드'라는 **프레임워크(시스템)**가 있다고 칩시다.
- 이 '신용카드' 하나로 결제도 하고, **할부(흐름 조절)**도 하고, **한도 초과 방지(혼잡 제어)**도 하죠?
- 이처럼 TCP에서도 '윈도우 크기 조절'이라는 하나의 **구조적 규칙(Frame)**을 가지고 에러, 흐름, 혼잡 제어를 싹 다 해결한다는 뜻에서 '프레임워크'라고 표현하신 겁니다. 단순히 도구(Tool)라기보다는 **"규칙이 있는 체계"**에 가깝습니다.
2. 개발(코딩)에서의 의미: "반조리 키트 (밀키트)"
보통 IT에서 "스프링 프레임워크", "장고 프레임워크" 할 때의 의미입니다. 이때는 **"개발을 쉽게 하기 위해 미리 만들어진 뼈대 코드"**를 말합니다.
- 비유: 요리를 한다고 칩시다.
- 프레임워크가 없는 경우: 밀가루 반죽부터 하고, 소스 만들고, 면 뽑고... (너무 힘듦)
- 프레임워크를 쓰는 경우: **밀키트(Meal Kit)**를 사옵니다. 면, 소스, 야채가 손질되어 있고 "3분 끓이세요"라는 규칙이 있죠. 나는 불만 켜면 됩니다.
- 의미: 개발자가 맨땅에 헤딩하지 않도록, 보안, DB 연결, 로그인 기능 같은 기초 공사를 미리 다 해놓은 **'반제품 소프트웨어'**를 뜻합니다.
3. 일반적인 의미 (비즈니스/생각): "사고의 틀"
경영학이나 기획에서 "SWOT 분석 프레임워크를 써보자"라고 할 때의 의미입니다.
- 의미: 생각을 중구난방으로 하지 말고, **정해진 틀(Frame)**에 맞춰서 정리하자는 **'생각의 공식'**입니다.
요약 (시험용)
질문하신 TCP 수업 문맥에서 "윈도우 프레임워크"라고 한 것은:
"TCP가 에러, 흐름, 혼잡 제어를 할 때 주먹구구식으로 하는 게 아니라, '윈도우(보낼 데이터 양)'를 조절하는 하나의 통일된 규칙과 구조(뼈대) 위에서 이 3가지를 모두 수행한다."
라고 이해하시면 가장 정확합니다. 단순히 '도구'보다 좀 더 거창하게 **'이 모든 것이 돌아가는 판'**이라고 생각하세요.
1. TCP 합의 실패가 심각하지 않은 이유 (군대 비유)
강의에서는 **'두 장군 문제(Two Generals Problem)'**를 비유로 들었습니다.
- 전쟁(군대) 상황:
- 두 부대가 동시에 공격하기로 합의해야 합니다.
- 만약 전령이 죽어서 한쪽만 공격하고 한쪽은 안 하면? -> 전쟁에서 지고 목숨이 날아갑니다. (매우 치명적)
- 그래서 100% 완벽한 합의가 필수적입니다.
- TCP 상황:
- 3-Way Handshake 과정에서 마지막 ACK가 사라지는 등의 이유로, 한쪽(A)은 "연결됐다"고 생각하는데, 다른 쪽(B)은 "연결 안 됐다(실패)"고 생각하는 상황이 발생할 수 있습니다.
- 이때 A가 데이터를 보냅니다. B 입장에서는 뜬금없는 데이터가 오겠죠?
- 결과: B가 "이게 누구야? 나 너 모르는데?" 하고 놀라는 게 전부입니다.
- 누가 죽거나, 시스템이 폭파되는 치명적인 일이 아닙니다. 그냥 "아, 서로 말이 안 맞았네?" 하고 다시 하면 그만이기 때문에 심각하지 않다고 한 것입니다.
2. "알 수 없는 녀석"과 "Reset (RST) 플래그"의 관계
이 상황을 해결하는 **"빠져나가는 방법"**이 바로 Reset 플래그입니다.
상황 예시 (합의 실패 상황)
- A (송신자): "연결 성공!"이라고 착각하고 있음. 그래서 신나게 데이터 패킷을 B에게 보냄.
- B (수신자): 연결 요청이 온 적 없거나 실패했다고 생각함. (연결 정보가 없음).
- 사건 발생: 갑자기 A로부터 데이터가 툭 도착함.
- B의 반응: "넌 누구냐? 난 너랑 연결 맺은 적 없는데 왜 데이터를 보내?" (이게 바로 '알 수 없는 녀석' 상황)
Reset (RST) 플래그의 동작
이때 B는 당황하지 않고, TCP 헤더의 플래그 중 RST(Reset) 비트를 1로 켠 패킷을 A에게 쏘아 보냅니다.
- B가 보내는 메시지의 의미 (RST):
- "야, 뭔가 오해가 있는 것 같은데(꼬였는데), 난 너랑 연결된 적 없어. 지금 보내는 거 싹 다 무시하고(Reset), 처음부터 다시 연결 요청하든지 해!"
- A의 반응 (RST를 받음):
- "아, 내가 연결됐다고 착각했구나. 뭔가 잘못됐네."
-> 즉시 현재 연결 시도를 **포기(Abnormal Termination)**하고, 처음부터(3-way handshake부터) 다시 시작합니다.
[시험용 핵심 요약]
- 심각하지 않은 이유:
- 군대처럼 목숨이 오가는 상황이 아님.
- 서로 상태가 안 맞아도(동기화 실패), 상대방이 "나 너 몰라"라고 거부하면 그만이기 때문.
- Reset (RST) 플래그의 역할:
- 상황: 수신자가 자신이 모르는(연결 정보가 없는) 연결의 패킷을 받았을 때.
- 동작: 수신자는 RST 플래그를 세팅한 패킷을 송신자에게 보냄.
- 결과: 송신자는 이를 보고 "연결이 꼬였음"을 인지하고, 연결을 강제로 끊거나 처음부터 다시 연결 설정을 시도함.
**"합의를 못한 건 똑같은데 왜 결과가 다르냐?"**라는 질문, 정말 날카롭고 좋은 질문입니다.
핵심은 **"실패했을 때 되돌릴 수 있느냐(복구 가능성)"**의 차이입니다.
강의에서 교수님이 말하고자 했던 포인트는 **"합의 실패 자체"가 아니라 "합의 실패의 대가(Penalty)"**가 다르다는 것입니다.
1. 전쟁 (두 장군 문제) : 되돌릴 수 없음 (Game Over)
- 상황: 장군 A는 "합의됐다"고 믿고 혼자 돌격합니다. 장군 B는 합의 안 됐으니 가만히 있습니다.
- 결과: 장군 A의 부대는 적군에게 포위되어 **전멸(사망)**합니다.
- 핵심: 죽은 사람은 되살릴 수 없습니다. "아, 합의 안 된 거였어? 미안, 다시 살려서 후퇴하고 처음부터 다시 공격하자!" 이게 불가능합니다.
- 결론: 그래서 여기선 합의 실패가 **치명적(Fatal)**입니다.
2. TCP : 되돌릴 수 있음 (Retry)
- 상황: 컴퓨터 A는 "합의됐다(연결됨)"고 믿고 데이터를 보냅니다. 컴퓨터 B는 연결 안 됐으니 모른 척합니다.
- 결과: 컴퓨터 B가 "누구세요?(RST)"라고 답장을 보냅니다. 데이터 전송은 실패합니다.
- 핵심: 데이터가 거부당했을 뿐, 컴퓨터가 폭발하거나 데이터가 영원히 소멸된 게 아닙니다. A는 "아, 합의 안 된 거였어? 미안, 그럼 처음(3-way handshake)부터 다시 시도할게!" 하고 다시 연결 요청을 보내면 됩니다.
- 결론: 0.1초 정도 늦어질 뿐, 결국 다시 연결해서 성공하면 되기 때문에 **심각하지 않다(Not Serious)**고 한 것입니다.
[한 줄 요약]
전쟁은 합의 실패 시 목숨을 잃고 리셋(Reset)이 불가능하지만,
TCP는 합의 실패 시 그냥 '리셋(RST) 플래그' 받고 다시 걸면 되기 때문에 심각하지 않다는 뜻입니다.
**ARQ(자동 재전송 요구)**와 **시퀀스 넘버(Sequence Number)**가 왜 뗄래야 뗄 수 없는 관계인지, 그리고 왜 연결 설정(Handshake) 때 이걸 교환해야 하는지 정리해 드릴게요.
핵심은 **"ARQ를 하려면 데이터에 '이름표(번호)'가 붙어 있어야 하기 때문"**입니다.
1. ARQ와 시퀀스 넘버의 관계
**ARQ(Automatic Repeat Request)**는 말 그대로 "제대로 안 왔으면 다시 보내달라고 요청하는 기술"입니다.
- 문제: 수신자가 "야, 안 왔어! 다시 보내!"라고 하려면, '무엇'이 안 왔는지를 콕 집어서 말해줘야 합니다.
- 해결: 데이터 조각마다 고유한 번호(Sequence Number)를 붙입니다.
- 수신자: "야, 100번은 받았는데 200번이 안 왔어. 200번 다시 보내줘."
- 송신자: "오키, 200번 재전송."
- 결론: 시퀀스 넘버가 없으면, 수신자는 데이터가 중간에 빠진 건지, 순서가 뒤집힌 건지 알 방법이 없습니다. 그래서 ARQ(신뢰성 있는 전송)를 하기 위한 가장 **기초 재료(기반 정보)**가 바로 시퀀스 넘버입니다.
2. 왜 연결 설정(3-Way Handshake) 때 이걸 교환해야 하나?
강의에서 **"첫 번째 시퀀스 넘버(ISN)를 모르면 문제가 된다"**고 했던 부분이 바로 이 설명입니다.
TCP는 보안상의 이유로 시퀀스 넘버를 0번부터 시작하지 않고, 랜덤한 숫자부터 시작합니다. (예: 5382번부터 시작).
만약 미리 안 알려주면 생기는 일 (강의 예시)
- 상황: A가 마음대로 100번부터 데이터를 보내기 시작함. (B한테 안 알려줌)
- B의 오해: B는 당연히 0번부터 시작할 줄 알고 기다리는데, 뜬금없이 100번 패킷이 도착함.
- B의 혼란:
- "어? 100번이 왔네? 그럼 앞의 0번~99번은 어디 갔지? 오다가 죽었나?"
- "아니면 얘가 원래 100번부터 시작인가?"
- 결과: B는 앞부분(0~99)이 빠졌다고 생각해서 하염없이 기다리거나, 100번을 버릴 수도 있습니다.
그래서 Handshake 때 하는 일
이런 오해를 막기 위해, 연결을 맺을 때(악수할 때) 서로의 **시작 번호(Initial Sequence Number)**를 명확히 교환합니다.
A: "안녕? 나랑 연결하자(SYN). 참고로 난 시퀀스 넘버 5000번부터 쓸 거야."
B: "알았어(ACK). 나도 연결할게(SYN). 난 시퀀스 넘버 8000번부터 쓸 거야."
이렇게 합의가 되면, 나중에 A가 5000번을 보내도 B는 "아, 이게 첫 번째 데이터구나" 하고 정확히 알 수 있게 됩니다.
[시험용 한 줄 요약]
- ARQ를 하려면 빠진 데이터를 콕 집어내기 위해 **번호(Sequence Number)**가 필수이다.
- TCP는 랜덤한 시작 번호를 쓰기 때문에, 연결 설정 시 서로 **"나 몇 번부터 시작한다"**고 미리 알려줘야(동기화해야) 첫 패킷인지 유실된 패킷인지 구분할 수 있다.
이 부분은 **"왜 TCP는 연결할 때(3-way handshake) 서로의 '시작 번호(Initial Sequence Number)'를 꼭 알려줘야 하는가?"**에 대한 이유를 설명하는 구간입니다.
쉽게 말해 **"기준점(0점)을 안 잡고 시작하면 생기는 끔찍한 오해"**를 설명하고 있습니다.
비유를 들어 아주 쉽게 이해시켜 드릴게요.
📖 책 페이지 비유
철수(송신자)가 영희(수신자)에게 찢어진 소설책 페이지를 한 장 줬습니다. 그 페이지 하단에는 **"10페이지"**라고 적혀 있습니다.
이때 영희는 **"이 소설책이 몇 페이지부터 시작하는지"**를 모르는 상태입니다.
영희의 딜레마 (이게 본문의 상황)
영희는 **"10페이지"**를 손에 들고 심각한 고민에 빠집니다.
- 가설 1 (원래 10페이지부터 시작인 경우):
- "이 소설은 특이하게 10페이지부터 시작하나 봐. 그럼 이게 첫 장이구나! 읽기 시작하면 되겠다."
- 가설 2 (원래 1페이지부터 시작인데 앞장이 사라진 경우):
- "보통 책은 1페이지부터잖아. 그럼 앞에 1~9페이지가 있었는데 배달 사고로 사라진 거 아냐?"
- "그럼 난 10페이지를 읽으면 안 돼. 1~9페이지가 올 때까지 기다려야지."
💥 "영원히 기다리는" 문제 발생
만약 **사실은 10페이지부터 시작하는 책(가설 1)**이었는데, 영희가 가설 2라고 착각해버리면 어떻게 될까요?
- 영희는 오지도 않을 유령 같은 1~9페이지를 하염없이 기다리게 됩니다.
- 철수는 "왜 안 읽어?" 하고 답답해하고, 영희는 "앞장 언제 줘?" 하고 멍하니 기다리는 **교착 상태(Deadlock)**에 빠집니다.
💻 컴퓨터(TCP) 상황으로 번역
본문의 "10분"은 오타이고 **"10번(Sequence Number 10)"**이라는 뜻입니다.
- 상황: 컴퓨터 A가 컴퓨터 B에게 데이터를 보냈는데, 그 번호가 10번입니다.
- 문제: A와 B는 시작 번호를 서로 합의하지(교환하지) 않았습니다.
- B의 고민:
- "A가 랜덤하게 10번부터 시작한 걸까? (이게 첫 패킷인가?)"
- "아니면 0번부터 시작했는데, 0~9번 패킷이 네트워크에서 사라지고(Loss) 10번만 온 걸까?"
- 결과: B가 "앞에 0~9번이 있었을 거야"라고 잘못 판단하면, 존재하지도 않는 패킷을 기다리느라 영원히 데이터를 처리하지 못하는 사고가 터집니다.
✅ 결론: 그래서 뭘 교환한다고?
이런 바보 같은 상황을 막기 위해 3-Way Handshake (연결 설정) 때 서로 명확하게 기준을 잡는 겁니다.
A: (SYN) "야, 나랑 연결하자. 참고로 내 책은 10페이지부터 시작해! (ISN = 10)"
B: (ACK) "알았어! 네 책은 10페이지가 시작이구나. 확인!"
이렇게 미리 **"내 시작 번호는 이거야!"**라고 알려주는 과정(동기화)이 있어야만, 나중에 10번이 왔을 때 "아, 이게 첫 번째 데이터구나!" 하고 오해 없이 바로 받아들일 수 있다는 뜻입니다.
질문하신 내용이 TCP의 3-Way Handshake와 Sequence/ACK 번호 규칙에서 가장 헷갈리는 부분입니다. 개념을 확실하게 잡아드릴게요.
가장 중요한 대원칙 2가지만 기억하세요.
- Seq (Sequence Number): "이번에 보내는 내 데이터의 번호" (나 기준)
- Ack (Acknowledgment Number): "다음에 받고 싶은 상대방의 데이터 번호" (너 기준)
1. 질문하신 내용 바로잡기
Q1. SYN은 제일 처음에만 하는 건가요?
- A: 네, 맞습니다.
- SYN(Synchronize) 플래그는 "우리 연결(동기화) 시작하자!"라는 뜻이라서, 맨 처음 연결 맺을 때(3-way handshake) 딱 한 번만 씁니다. 데이터 주고받을 땐 안 씁니다.
Q2. ACK은 상대를 기준으로 하는 건가요?
- A: 네, 정확합니다.
- ACK 숫자의 의미는 **"너(상대방)의 패킷 OO번까지 잘 받았으니, 이제 OO+1번을 보내줘"**라는 뜻입니다. 철저히 상대방 시퀀스 넘버에 반응하는 숫자입니다.
Q3. Seq랑 Ack랑 같나요?
- A: 아뇨, 완전히 따로 놉니다.
- 내가 보내는 번호(Seq)와 내가 받고 싶은 번호(Ack)는 별개의 흐름입니다. (전화 통화할 때 내 말과 상대방 말이 따로 있는 것과 같습니다.)
2. "m+1"의 정체 (3-Way Handshake로 설명)
상황을 설정해볼게요.
- A (나): 시작 번호를 100번(m)으로 정함.
- B (상대): 시작 번호를 5000번(n)으로 정함.
이 숫자들이 어떻게 m+1, n+1이 되는지 보세요.
[1단계] A -> B (연결 요청)
- A: "야, 나랑 연결하자(SYN). 내 시작 번호는 100번(m)이야."
- Seq = 100 (m)
- Ack = 0 (아직 받은 게 없으니 의미 없음)
[2단계] B -> A (수락 및 내 번호 알림)
- B: "그래! 네꺼 100번(m) 잘 받았어. 그러니까 다음엔 101번(m+1) 줘. 그리고 내 시작 번호는 5000번(n)이야."
- Seq = 5000 (n) <-- 이건 자기(B) 번호
- Ack = 101 (m+1) <-- 이건 A한테 요구하는 번호 ("100번은 잘 받았고 101번 내놔")
[3단계] A -> B (마지막 확인)
- A: "오키! 네꺼 5000번(n) 잘 받았어. 그러니까 다음엔 5001번(n+1) 줘. 자 이제 내가 101번(m+1) 보낸다."
- Seq = 101 (m+1) <-- 아까 B가 달라고 했던 그 번호
- Ack = 5001 (n+1) <-- B의 5000번 확인했으니 다음 거 달라는 요청
[시험용 요약 정리]
- SYN: 맨 처음 연결할 때 "나 여기(번호)부터 시작할게!"라고 알리는 깃발.
- Seq (시퀀스 넘버): 지금 보내는 내 패킷의 번호표.
- Ack (에크 넘버): 상대방한테 하는 말 -> "방금 받은 번호(m) 다음 번호(m+1)를 나한테 보내줘." (Next Expected Sequence Number)
[공식처럼 외우기]
- 상대방이 Seq = m을 보냈다.
- 나는 답장으로 Ack = m + 1을 보낸다. ("m까지 잘 받았고, m+1 내놔")

녹취록에 있는 **"연결 끊을 때(Teardown)"**의 시퀀스 넘버와 ACK 규칙, 아주 명쾌하게 정리해 드릴게요.
핵심은 **"연결 끊을 때 쓰는 FIN 플래그도 SYN처럼 가상의 1바이트를 차지한다(그래서 +1 한다)"**는 점입니다.
1. 연결 끊기: 4-Way Handshake (기본 과정)
연결할 때는 3번 만에 끝나지만(3-Way), 끊을 때는 서로 "나 이제 할 말 없어"라고 확인해야 해서 보통 4번 왔다 갔다 합니다.
이때 숫자가 어떻게 변하는지 **예시(A와 B)**로 보세요.
(가정: A는 100번까지 보냈고, B는 5000번까지 보낸 상태)
[1단계] A -> B (나 그만 끊을래)
- A: "나 이제 보낼 데이터 없어. 끝낼게(FIN)."
- Seq = 100
- FIN 플래그 = ON
[2단계] B -> A (어, 알았어)
- B: "그래? A 너는 할 말 다 끝났구나. 확인(ACK)."
- Ack = 101 (중요: FIN도 1로 쳐서 100 + 1 = 101)
- (참고: 이때 B는 아직 할 말이 남았다면 데이터를 계속 보낼 수 있습니다. A는 듣기만 가능.)
[3단계] B -> A (나도 이제 끊을래)
- B: "나도 이제 정리 다 됐어. 진짜 끝내자(FIN)."
- Seq = 5000
- FIN 플래그 = ON
[4단계] A -> B (그래, 잘 가라)
- A: "오키, 너도 끝났구나. 확인(ACK). 바이바이."
- Ack = 5001 (중요: B의 FIN도 1로 쳐서 5000 + 1 = 5001)
2. 녹취록의 특이 사항: "3번 만에도 가능하다?"
교수님이 "끊을 때도 패킷 3번이면 될 겁니다"라고 하신 부분은 2단계와 3단계를 합쳤을 때를 말합니다.
- B가 A의 종료 요청(ACK)을 보내면서, 동시에 "나도 끝낼래(FIN)"를 한 패킷에 몰아서(Piggyback) 보낼 수도 있습니다.
- FIN + ACK 플래그를 동시에 켜서 보내면 패킷 하나가 줄어들어 3번 만에 끝납니다.
[시험용 핵심 요약]
- FIN 플래그의 규칙:
- SYN과 똑같습니다. 데이터는 없지만 중요한 신호이므로 시퀀스 넘버 1을 잡아먹습니다.
- 따라서 상대방은 ACK를 보낼 때 반드시 **받은 번호 + 1**을 해줘야 합니다.
- 반쪽짜리 종료 (Half-Close):
- A가 FIN을 보냈다고 해서 연결이 뚝 끊기는 게 아닙니다.
- "나는(A) 더 이상 보낼 게 없다"는 뜻이지, "듣지도 않겠다"는 뜻은 아닙니다.
- B가 FIN을 보내기 전까지는 A는 B의 말을 계속 들어줘야 합니다.
녹취록에서 교수님이 "물(Stream)처럼 흐른다", **"마음대로 자른다"**라고 하신 부분, 처음 들으면 정말 뜬구름 잡는 소리 같죠?
하지만 이 개념이 TCP와 UDP를 가르는 가장 결정적인 차이이자, TCP의 시퀀스 넘버가 왜 그렇게 생겨먹었는지를 설명하는 핵심입니다.
시험에 바로 쓸 수 있게 비유와 예시로 딱 정리해 드릴게요.
1. "스트림(Stream)이다" = "물줄기"다
가장 쉬운 비유는 **'수도꼭지와 물통'**입니다.
- UDP (메시지 방식): '택배 상자' 같습니다.
- 응용 프로그램이 "자, 여기 사과 한 상자(데이터 1덩어리)"라고 주면, UDP는 그 상자 그대로 테이프 붙여서 보냅니다.
- 받는 사람도 "어? 사과 한 상자 왔네" 하고 상자 단위로 받습니다. 경계가 뚜렷하죠.
- TCP (스트림 방식): '수도 호스' 같습니다.
- 응용 프로그램(예: 카톡)이 데이터를 보내면, TCP라는 **큰 물통(버퍼)**에 물(데이터)을 콸콸 붓습니다.
- TCP는 이 물통에 담긴 물을 호스를 통해 상대방에게 보냅니다.
- 핵심: 물통에 물이 차 있으면, TCP가 자기 마음대로 컵으로 퍼서 보내든, 바가지로 퍼서 보내든 상관없습니다.
- 받는 사람 입장에서는 그냥 **"물이 계속 들어오네?"**라고 느낄 뿐, 이게 원래 한 컵이었는지 한 바가지였는지 구분할 필요가 없습니다. 이것을 **"경계(Boundary)가 없다"**라고 합니다.
2. "마음대로 자른다"의 의미 (세그먼트)
물이 계속 흐르지만, 인터넷 선(케이블)은 한 번에 보낼 수 있는 크기(트럭 크기)가 정해져 있습니다. 그래서 TCP는 물통(송신 버퍼)에 있는 데이터를 적당히 잘라서 포장해야 합니다. 이 잘린 조각을 **세그먼트(Segment)**라고 합니다.
녹취록의 "재전송할 때 사이즈가 다를 수 있다"는 말의 뜻
이게 진짜 중요합니다.
- 상황: TCP가 처음에 데이터를 1000 바이트만큼 잘라서(세그먼트 A) 보냈습니다.
- 사고: 근데 이 패킷이 가다가 사라졌습니다(Loss).
- 재전송: TCP가 다시 보내려고 보니, 지금 네트워크 길이 좁아져서 1000 바이트는 너무 큰 것 같습니다.
- TCP의 행동: "어차피 이건 물(바이트)이니까, 굳이 아까처럼 1000 바이트 한 덩어리로 보낼 필요 없지. 500 바이트씩 두 번에 나눠서 보내자."
- 결과: 1000 바이트짜리 하나가 사라졌는데, 재전송할 때는 500 바이트짜리 두 개가 날아갑니다. 그래도 상관없습니다. 받는 쪽에선 어차피 합치면 똑같은 물이니까요.
- 이게 바로 **"패킷(세그먼트)의 경계가 고정되어 있지 않고 마음대로 자른다"**는 뜻입니다.
3. "페이로드 전체에서 몇 번째..." (시퀀스 넘버의 진짜 의미)
데이터를 마음대로 뚝뚝 자르니까, "이게 몇 번째 조각이야?"(패킷 번호 1번, 2번...)라고 붙이는 건 의미가 없습니다. (아까는 1번 패킷이었는데, 재전송할 땐 쪼개져서 1-1번, 1-2번이 될 수도 있으니까요.)
그래서 TCP는 조각(패킷)에 번호를 붙이는 게 아니라, 내용물(바이트) 하나하나에 번호(주소)를 매깁니다.
[강의 예시 해석]
"시퀀스 넘버가 92번이고, 데이터가 8바이트다."
- 이 말은: "이 택배 상자 안에 든 데이터는, 전체 책 내용 중에서 **92번째 글자부터 시작해서 8글자(92~99번째)**가 들어있어." 라는 뜻입니다.
- 다음 패킷: 그럼 다음 택배 상자는 몇 번부터 시작할까요? 99번까지 보냈으니 100번부터 시작하겠죠?
- 그래서 Seq 92 + 8 bytes = Next Seq 100이 되는 것입니다.
[시험용 요약]
- 스트림(Stream): 데이터에 칸막이(경계)가 없다. 물처럼 쭉 이어진 데이터(Byte)의 흐름이다.
- 마음대로 자른다: TCP는 네트워크 상황(MTU, 윈도우 크기 등)에 맞춰서 버퍼에 있는 데이터를 자기가 원하는 크기만큼 뚝 떼어내서(Segment) 보낸다. 재전송 시 크기가 달라져도 된다.
- 시퀀스 넘버: 패킷 번호(1탄, 2탄)가 아니라, **"전체 데이터 중 몇 번째 바이트부터 시작하는지"**를 나타내는 **위치 번호(Offset)**이다.
네, **"다음은 100 + 20이라서 크기가 달라서인가?"**라고 추측하신 부분이 정답이자 핵심입니다.
이 부분에서 스트림(Stream) 개념이 나오는 이유는 **"번호가 1씩(패킷 개수대로) 늘어나는 게 아니라, 보낸 크기(바이트)만큼 퍽퍽 늘어나기 때문"**입니다.
그 둘의 연관성을 시험에 쓸 수 있게 딱 정리해 드릴게요.
1. 스트림(Stream)과 시퀀스 넘버의 관계
만약 TCP가 스트림 방식이 아니라면(메시지 방식이라면) 번호는 이렇게 붙었을 겁니다.
"이건 1번 패킷이야(크기 8 바이트)."
"이건 2번 패킷이야(크기 20 바이트)."
"이건 3번 패킷이야."
(번호: 1 -> 2 -> 3, 규칙적임)
하지만 TCP는 스트림(바이트의 흐름) 방식이기 때문에, "패킷의 개수"를 세지 않고 "지금까지 보낸 물(데이터)의 양"을 셉니다.
"지금 92번째 물방울부터 보낼게. (크기 8방울)" -> (92
99번 보냄)119번 보냄)
"자, 이제 100번째 물방울부터 보낼 차례네. 이번엔 20방울 보낼게." -> (100
"그럼 다음은 120번째 물방울부터..."
(번호: 92 -> 100 -> 120, 크기에 따라 불규칙하게 뜀)
[결론]
Seq 92 + 8 = Next Seq 100이라는 계산 자체가 **"나는 패킷 1개, 2개를 세는 게 아니라, 바이트(내용물)의 양을 세고 있다"**는 증거입니다. 이게 바로 스트림의 정의입니다.
2. 강의 예시 분석 (92, 100, 120...)
강의에서 나온 상황을 스트림 개념으로 풀면 이렇습니다.
- 첫 번째 세그먼트:
- Seq: 92 (92번 바이트부터 시작)
- 크기: 8 바이트
- 결과: 92번부터 99번까지 보냈음. -> "다음엔 100번 줄게."
- 두 번째 세그먼트:
- Seq: 100 (앞에서 99번까지 보냈으니까)
- 크기: 20 바이트 (이번엔 좀 많이 잘랐음)
- 결과: 100번부터 119번까지 보냈음. -> "다음엔 120번 줄게."
- 세 번째 세그먼트:
- Seq: 120 (앞에서 119번까지 보냈으니까)
[질문하신 포인트]
"다음은 100+20이라서..."
네, 맞습니다! 앞의 패킷이 8바이트였으면 번호가 8만큼 늘어나고, 다음 패킷이 20바이트면 번호가 20만큼 늘어납니다.
"보내는 크기(양)에 따라 번호가 고무줄처럼 늘어나는 것", 이것이 바로 데이터를 연속된 흐름(Stream)으로 본다는 뜻입니다.
[시험용 요약]
- 질문: 왜 Seq 92 + 8 = 100 계산 설명에서 스트림 개념이 나오는가?
- 정답: 시퀀스 넘버가 '패킷의 순서(1, 2, 3)'가 아니라 **'데이터의 바이트 위치(92, 100, 120)'**를 나타내기 때문이다.
- 이유: TCP는 데이터를 덩어리(메시지)가 아니라 **연속된 바이트의 흐름(Stream)**으로 취급하기 때문에, "이전 패킷의 크기(Byte)"만큼 시퀀스 넘버가 증가한다.


4+1 생각해보면


1. Go-Back-N (GBN) = 누적 ACK의 정석 (O)
Go-Back-N은 누적 ACK(Cumulative ACK)를 사용하는 대표적인 방식이 맞습니다.
- 동작:
- 수신자는 순서대로 오지 않은 패킷은 싹 다 갖다 버립니다. (저장 안 함)
- 1번 받고, 2번 안 오고, 3번이 오면? -> 3번 버림.
- 그리고 계속 외칩니다. "야! 2번 안 왔어! 2번 내놔! (ACK 2)"
- 특징:
- ACK n의 의미가 **"n-1번까지 완벽하게 받았다"**는 뜻이므로, 100% 누적 ACK입니다.
2. Selective Repeat (SR) = 개별 ACK (누적 ACK 아님) (X)
Selective Repeat는 원칙적으로 **누적 ACK가 아니라 '개별 ACK (Individual ACK)'**를 사용합니다.
- 동작:
- 1번 받고, 2번 안 오고, 3번이 오면? -> 3번을 버퍼에 저장함. (님 말씀대로)
- 그리고 답장을 보냅니다. "나 3번 받았음. (ACK 3)"
- 이때의 ACK 3은 "앞에 거 다 받았다"는 뜻이 아니라, **"딱 3번 그 녀석만 받았다"**는 뜻입니다.
- 이유:
- 중간에 구멍(2번)이 뻥 뚫려 있는데 "3번까지 다 받았다"고 누적 ACK를 보내면 거짓말이 되니까요.
3. 근데 왜 교수님은 "TCP는 SR이랑 비슷한데 누적 ACK다"라고 했을까? (여기가 시험 포인트)
TCP는 **[Go-Back-N의 ACK 방식]**과 **[Selective Repeat의 버퍼링 방식]**을 섞어놓은 **혼종(Hybrid)**이기 때문입니다.
- TCP의 행동 (강의 내용):
- 버퍼링 (SR 특징): 2번이 안 오고 3번이 오면? -> 3번을 버리지 않고 저장해둡니다. (SR처럼 효율적임)
- ACK 보내기 (GBN 특징): 하지만 답장은 **ACK 2 (2번 내놔)**라고 보냅니다.
- 왜? TCP 헤더의 문법이 누적 ACK이기 때문입니다. 2번이 비어있으면 죽어도 3번 받았다고 말을 못 합니다.
[요약: TCP의 딜레마와 해결]
- 문제: 3번을 잘 받아놓고도, 문법(누적 ACK) 때문에 송신자한테 "나 3번 잘 받았어"라고 말을 못 합니다. (계속 "2번 줘"라고만 함)
- 송신자의 오해: "어? 얘가 2번 달라고 하네? 그럼 3번도 못 받았나 보다." 하고 2번, 3번을 다 다시 보낼 수도 있습니다. (비효율)
- 해결 (SACK 옵션): 그래서 현대 TCP는 **SACK(Selective ACK)**이라는 옵션을 켜서, **"공식적으론 2번 기다리는데(누적), 참고로 뒤에 3번은 잘 받아뒀어(개별)"**라고 귓속말을 해줍니다.
[시험용 표 정리]
| 방식 | ACK 방식 | 순서 안 맞으면(Out-of-order) | 비고 |
| Go-Back-N | 누적 ACK | 버림 (Discard) | 순서대로만 받음 |
| Selective Repeat | 개별 ACK | 저장함 (Buffer) | 쏙쏙 골라서 받음 |
| TCP (실제) | 누적 ACK | 저장함 (Buffer) | GBN의 문법 + SR의 효율성 |
[결론]
- Go-Back-N은 누적 ACK가 맞습니다.
- Selective Repeat는 원래 개별 ACK입니다.
- 하지만 TCP는 **"누적 ACK를 쓰면서도 SR처럼 뒤에 걸 저장하는 방식"**을 씁니다. (그래서 강의에서 "TCP는 SR과 비슷하지만 누적 ACK를 쓴다"고 설명한 것입니다.)


**ARQ(Automatic Repeat Request)**가 오류 제어를 하는 원리는 아주 단순하고 무식합니다.
한마디로 요약하면 **"제대로 도착할 때까지 끈질기게 다시 보내기(재전송)"**입니다.
어떻게 '오류'를 잡아서 '정상'으로 만드는지, 3단계 메커니즘으로 딱 정리해 드릴게요.
1단계: 검사 (Error Detection) - "이거 상했나?"
수신자가 패킷을 받으면 가장 먼저 하는 일이 있습니다. 바로 체크섬(Checksum) 검사입니다.
- 상황: 송신자가 보낸 데이터가 오는 도중에 노이즈가 껴서 0이 1로 바뀌거나 깨졌습니다.
- 수신자의 행동:
- 수학적으로 계산(Checksum)을 해봅니다.
- "어? 송신자가 보낸 값이랑 내가 계산한 값이 다르네?"
- 판단: "이 패킷은 쓰레기다."
- 조치: 그 즉시 패킷을 가차 없이 버립니다(Drop). (아예 안 받은 셈 칩니다.)
2단계: 침묵 또는 독촉 (Feedback) - "안 왔어!"
수신자가 패킷을 버렸거나, 아예 도착조차 안 했습니다. 송신자는 이 사실을 알아야 합니다.
- 방법 1 (타임아웃):
- 수신자는 쓰레기 패킷을 버렸으니 **ACK(잘 받았다는 답장)**를 안 보냅니다.
- 송신자는 하염없이 기다리다가 **"어? 시간이 꽤 지났는데(Timer) 답장이 안 오네?"**라고 깨닫습니다.
- 방법 2 (중복 ACK):
- 수신자가 뒤에 도착한 다른 패킷 때문에 **"야! 나 아까 그 번호 못 받았어!(ACK N)"**라고 계속 소리칩니다.
3단계: 재전송 (Retransmission) - "새 걸로 다시 줄게"
여기가 **오류 제어(Error Control)**가 완성되는 순간입니다.
- 송신자의 행동: "아, 아까 보낸 게 깨졌거나 잃어버렸구나. 똑같은 걸로 다시 보낸다!"
- 결과:
- 수신자는 결국 멀쩡한 새 패킷을 다시 받게 됩니다.
- 체크섬 검사 통과 -> ACK 발송.
[결론] 왜 이걸 '오류 제어'라고 부르는가?
보통 '오류 제어'라고 하면 깨진 데이터를 수신자가 마법처럼 **"고친다(Repair)"**고 생각하기 쉬운데, ARQ는 고치는 게 아닙니다.
"깨진 건 쿨하게 버리고, 멀쩡한 게 올 때까지 계속 다시 달라고 조른다."
이 과정을 통해 결과적으로 수신자는 무조건 '오류 없는 깨끗한 데이터'만 갖게 되므로, 이것을 **오류 제어(Error Control)**라고 부르는 것입니다.
[시험용 키워드 3형제]
- Checksum: 오류 감지 (깨지면 버림)
- Timer / ACK: 손실 확인 (안 왔음을 알림)
- Retransmission: 복구 (다시 보내서 해결)
1. 윈도우 기반 동작 (Window-based)
"송신자 윈도우 크기: K, 수신자 윈도우 크기: M"
- 의미: 한 번에 하나씩 보내고 기다리는 게 아니라, 와장창(Window 크기만큼) 보낸다는 뜻입니다.
- K와 M: 그냥 수학적인 기호입니다. 송신자(K)와 수신자(M)가 **각자 넉넉한 크기의 버퍼(물통)**를 가지고 있다는 뜻입니다.
- 핵심: 버퍼가 크기 때문에 **파이프라이닝(Pipelining)**이 가능합니다. (ACK 안 왔어도 일단 계속 쏘는 것)
2. 수신자 (Receiver) ★ 가장 중요
여기가 아까 제가 말씀드린 **'TCP의 하이브리드(혼종) 특성'**이 적혀 있는 부분입니다.
(1) "수신되는 패킷은 일단 저장 (SR과 유사)"
- 해석: 아까 질문하신 "0, 1 받고 2 손실되고 3 왔을 때" 상황입니다.
- Go-Back-N은 3을 버리지만, TCP는 3을 버리지 않고 저장합니다. 이게 **Selective Repeat(SR)**과 비슷하다는 뜻입니다. (효율적임)
(2) "누적 ACK 방식"
- 해석: 저장(버퍼링)은 SR처럼 똑똑하게 해놓고, 말(ACK)은 GBN처럼 "빈칸(2번)"만 계속 부릅니다.
- 이게 바로 **"SR처럼 저장하고, GBN처럼 말한다"**는 TCP의 정체성입니다.
(3) "오류 없이 수신되면 매번 ACK 회신"
- 해석: 패킷 받을 때마다 꼬박꼬박 답장(ACK)을 보낸다는 뜻입니다. (물론 Delayed ACK으로 좀 미룰 수는 있지만 원칙은 그렇습니다.)
3. 송신자 (Sender)
(1) "일련번호가 가장 낮은 'outstanding 패킷'에 대한 ACK가 수신되면 윈도우 이동"
- Outstanding 패킷이란?
- "보내긴 했는데, 아직 잘 받았다는 확인(ACK)을 못 받은 패킷"을 말합니다. (불안한 상태)
- 윈도우 이동 (Sliding Window):
- 가장 오래된 놈(가장 낮은 번호)의 ACK가 도착하면, "아, 해결됐다!" 하고 윈도우(창문)를 옆으로 쓱 밉니다.
- 윈도우가 밀리면 새로운 데이터를 보낼 공간이 생깁니다.
(2) "패킷마다 타이머 유지"
- 해석: 보낸 패킷 하나하나마다 옆에 **타이머(폭탄)**를 켜둡니다. 시간이 다 될 때까지 ACK가 안 오면 터지면서 재전송합니다.
- (참고: 실제 구현은 타이머 하나로 관리하기도 하지만, 논리적으로는 각자 타이머가 있다고 봅니다.)
[시험용 한 줄 요약]
이 슬라이드는 TCP ARQ의 3대 특징을 요약한 것입니다.
- 윈도우: 넉넉하게 많이 보낸다.
- 수신자: SR처럼 저장하지만, **ACK는 누적(GBN 스타일)**으로 보낸다. (가장 중요)
- 송신자: 안 온 놈(Outstanding)이 해결되어야만 윈도우를 밀고 앞으로 나간다.
이 슬라이드는 교수님께서 녹취록 중간에 말씀하신 **"TCP의 땜빵(성능 개선) 알고리즘 3대장"**을 정리한 것입니다.
TCP가 처음 만들어지고 나서 써보니 "너무 비효율적인데?" 싶은 부분들을 고치기 위해 추가된 기능들입니다. 시험에 정말 잘 나오는 내용이니 딱 정리해 드릴게요.
1. Delayed ACK (지연된 ACK) - [수신자용]
"ACK를 매번 보내지 말고, 조금 참았다가 한 번에 퉁치자."
- 상황: 수신자가 패킷 하나 받자마자 바로 ACK를 쏘면, 네트워크에 ACK 패킷이 너무 많아집니다.
- 동작:
- 패킷이 도착해도 바로 ACK를 안 보내고 잠깐(보통 0.2초 정도) 기다립니다.
- 기다리는 동안 패킷이 더 오면? -> **누적 ACK(Cumulative ACK)**로 한 방에 처리합니다. (ACK 2개 보낼 거 1개로 감소)
- 기다리는 동안 내가 보낼 데이터가 생기면? -> 데이터 패킷에 ACK를 업어서(Piggyback) 같이 보냅니다.
- 단점: 너무 오래 기다리면 송신자가 "어? 안 갔나?" 하고 재전송해버릴 수 있으니 적당히 기다려야 합니다.
2. Nagle의 알고리즘 (네이글 알고리즘) - [송신자용]
"데이터가 작으면 바로 보내지 말고, 모아서 보내자."
- 배경 (강의 예시):
- 채팅이나 명령어 입력(CLI) 같은 경우, 'a' 한 글자(1바이트)를 보내려고 헤더(40바이트)를 붙여서 보내면 배보다 배꼽이 더 큽니다. (비효율)
- 동작:
- 보낼 데이터가 작으면 일단 안 보내고 버퍼에 모읍니다.
- (1) 데이터가 한 트럭(MSS 크기)만큼 꽉 차거나,
- (2) 이전에 보낸 패킷의 ACK(확인)가 도착하면,
- 그때 모아둔 걸 한 번에 보냅니다.
- 비유: 버스 기사가 손님 1명 탔다고 출발 안 하고, 만석이 되거나 배차 시간 될 때까지 기다렸다가 출발하는 것.
- 단점: 반응속도가 중요한 FPS 게임 같은 곳에서는 **렉(Delay)**이 걸리므로 이 기능을 끕니다.
3. Fast Retransmission (빠른 재전송) - [가장 중요]
"타이머 터질 때까지 기다리면 거북이다. 3번 독촉하면 바로 다시 보내라."
- 문제점 (Why?):
- TCP 타이머는 평균 + 4*표준편차로 설정돼서 엄청 깁니다.
- 패킷이 진짜 손실됐는데 타이머 터질 때까지 기다리면, 그동안 송신자는 아무것도 못 하고 멍때립니다. -> 전송 효율(Throughput) 급격히 감소.
- 해결책 (3 Duplicate ACKs):
- 수신자가 **"야! 100번 내놔! (ACK 100)"**를 **3번 연속(중복)**으로 보내면?
- 송신자 판단: "아, 이건 타이머 기다릴 필요 없다. 100번은 확실히 죽었구나."
- 동작: 타이머가 아직 안 터졌어도 즉시 100번을 재전송합니다.
[시험 대비 요약]
이 슬라이드에서 외워야 할 포인트는 이겁니다.
- Delayed ACK (수신자): ACK 개수 줄여서 네트워크 효율 높임.
- Nagle (송신자): 작은 패킷을 합쳐서 보내서 헤더 낭비 줄임.
- Fast Retransmission:
- Why? 타이머 기다리면 성능(Throughput)이 떡락하니까.
- How? 중복 ACK 3개 받으면 즉시 재전송.
정말 좋은 의문입니다! **"어차피 순서가 틀렸다는 건데, 1개나 2개만 중복으로 와도 바로 다시 보내면 더 빠른 거 아냐?"**라고 생각하는 게 아주 합리적입니다.
하지만 TCP 설계자들이 굳이 **'3개'**까지 기다리는 데는 결정적인 이유가 있습니다. 바로 "패킷 순서 뒤바뀜(Reordering)" 때문입니다.
결론부터 말하면: **"설레발치다가 낭비하지 않기 위해서"**입니다.
1. "손실(Loss)" vs "지각(Reordering)"
인터넷은 복잡해서, 먼저 보낸 패킷이 나중에 도착하는 경우가 꽤 흔합니다.
- 상황: 송신자가 1, 2, 3, 4, 5번을 보냈습니다.
- 네트워크: 2번 패킷이 잠깐 딴 길로 새서(지연), 3번과 4번보다 늦게 도착할 수도 있습니다. (손실된 게 아님!)
만약 중복 ACK 1~2개에서 바로 재전송한다면? (성급한 경우)
- 1번 도착: 수신자 -> ACK 2 (정상)
- 3번 도착 (2번보다 먼저):
- 수신자: "어? 2번 안 왔는데 3번이 왔네? ACK 2 (중복 1)"
- 송신자 (성급함): "어! 중복 ACK다! 2번 죽었나 봐! 즉시 재전송!"
- 2번 도착 (그냥 늦은 거였음):
- 수신자: "어? 아까 안 온 2번 이제 왔네. 근데... 방금 송신자가 2번 또 보냈네?"
- 결과: 멀쩡히 살아있는 2번 패킷을 또 보내느라 네트워크 대역폭 낭비 + 송신자는 혼잡한 줄 알고 속도 줄임(손해).
2. 왜 하필 '3개'인가? (경험적 법칙)
TCP 개발자(제이콥슨 등)가 실제로 인터넷을 돌려보면서 통계를 내봤습니다.
- 중복 ACK 1~2개: "아, 이건 진짜 손실이라기보다는, 그냥 패킷 순서가 살짝 뒤집혀서(Reordering) 늦게 오는 경우가 많더라."
- 중복 ACK 3개: "야, 뒤에 3, 4, 5번이 도착할 때까지(ACK 3번 쏠 때까지) 2번이 안 온 거면, 이건 지각이 아니라 진짜 죽은(Loss) 확률이 99%다."
즉, 3개라는 숫자는 **"단순 지각(Reordering)은 걸러내고, 진짜 손실(Loss)만 잡아내기 위한 마지노선"**입니다.
[상황 시뮬레이션: 중복 ACK 3개의 의미]
송신자가 2번을 보냈는데, 수신자가 계속 **"2번 줘(ACK 2)"**라고 외치는 상황입니다.
- (ACK 2) -> "2번 아직 안 왔어."
- (ACK 2) Dup 1 -> "뒤에 3번 도착했는데도 2번 안 왔어."
- (ACK 2) Dup 2 -> "뒤에 4번 도착했는데도 2번 안 왔어."
- (ACK 2) Dup 3 -> "뒤에 5번 도착했는데도 2번 안 왔어."
송신자 판단:
"뒤에 보낸 패킷이 3개나 도착할 동안 2번이 안 왔다고? 이 정도로 순서가 심하게 뒤집힐 리는 없다. 2번은 죽은 게 확실하다. 재전송하자!"
[시험용 요약]
Q: 왜 중복 ACK 1~2개가 아니라 3개인가?
A: 불필요한 재전송(Spurious Retransmission)을 막기 위해서.
- 패킷이 손실된 게 아니라 단순히 순서가 뒤바뀌어(Reordering) 늦게 도착하는 경우에도 중복 ACK가 발생할 수 있다.
- 중복 ACK 1~2개 정도는 "순서 바뀜"일 확률이 높지만, 3개가 연속으로 오면 "진짜 손실"일 확률이 매우 높다는 통계적/경험적(Heuristic) 기준이다.




녹음본에서 교수님은 이 공식을 **"튀는 값(노이즈)을 잠재우고, 부드러운 평균(추세)을 찾아가는 과정"**으로 설명하셨습니다.
녹음본의 흐름 그대로 3단계로 나누어 설명해 드릴게요.
1. 문제 제기: "파란 점(실제 값)은 너무 출렁거린다"
교수님은 먼저 그래프 이야기를 하셨습니다.
- 상황: "측정된 RTT 값(SampleRTT)을 점으로 찍어보면 파란색 점처럼 나옵니다."
- 문제: "보시다시피 일정한 게 아니라 **엄청나게 출렁출렁(Fluctuation)**합니다. 이걸 그대로 타이머로 쓰면 타이머도 미친 듯이 널뛰기를 하겠죠?"
2. 해결책: "빨간 선(평균)을 만들자" (Moving Average)
그래서 **"들쑥날쑥한 파란 점들을 부드러운 빨간 선으로 바꾸는 공식"**이 필요하다고 했습니다.
- 용어: 신호 처리에서는 **'로패스 필터(Low-pass Filter)'**라고 하고, 보통은 **'무빙 에버리지(Moving Average, 이동 평균)'**라고 부른다고 하셨죠.
- 공식의 의미 ():"이번에 측정한 값(Sample)은 12.5%만 반영하고,
기존에 내가 알고 있던 평균(Estimated)을 87.5% 반영해서 섞겠다." - α=0.125\alpha = 0.125
- 효과: 이렇게 하면 방금 측정한 RTT가 갑자기 튀어도, 전체 평균값은 천천히 부드럽게 변합니다. (그래프의 빨간 선처럼)
3. 결론: "그래서 타이머는 얼마로?" (평균 + 4배 마진)
마지막으로 가장 중요한 **타이머 설정 값(TimeoutInterval)**을 정합니다.
- 질문: "평균값으로 타이머를 설정하면 어떻게 될까요?"
- 답변: "평균이라는 건 절반은 그것보다 크다는 뜻이잖아요? 그럼 날이면 날마다(50% 확률로) 타이머가 터질 겁니다. 이러면 망하죠."
- 해결: "그래서 통계학의 **표준편차(Deviation)**를 구해서 마진을 둡니다."
- 최종 공식: 평균 RTT + (4 * 표준편차)
- 교수님 설명: "정규분포에서 표준편차의 4배만큼 여유를 두면, 그 범위를 벗어날 확률은 0.00...% 수준으로 거의 없습니다. 아주 넉넉하고 보수적인 값으로 타이머를 잡는 겁니다."
[시험용 핵심 키워드]
녹음본 내용을 바탕으로 서술형 답안을 쓴다면 이 단어들이 꼭 들어가야 합니다.
- 무빙 에버리지 (Moving Average): 실제 RTT 값의 변화가 너무 심해서, 가중치를 두어 평균을 부드럽게 만드는 방법.
: 최신 측정값은 **1/8 (12.5%)**만 반영하고, 과거의 역사를 7/8 (87.5%) 반영하여 급격한 변화를 막는다.- α=0.125\alpha = 0.125
- 표준편차의 4배: 타이머가 너무 자주 터지는 것을 막기 위해, 평균보다 **아주 넉넉한 마진(Safety Margin)**을 둔다.
우리의 원래 목적: "안 온 패킷을 '언제' 재전송할까?"
우리는 지금 TCP의 에러 제어(Error Control), 그중에서도 **재전송(Retransmission)**을 공부하고 있습니다.
- 패킷을 보냈는데 ACK가 안 옵니다. (손실된 것 같음)
- 그럼 다시 보내야(Retransmit) 합니다.
- 근데 "얼마나 기다렸다가" 다시 보낼까요?
- 1초? 10초? 0.001초?
- 이 **기다리는 시간(타이머 값)**을 정해야 합니다.
**RTT(Round Trip Time)**는 바로 "이 타이머 시간을 정확하게 정하기 위해서" 측정하는 것입니다.
왜 RTT가 필요한가? (타이머 눈치 게임)
서울에서 부산으로 택배를 보낸다고 칩시다.
- 상황: 택배가 도착했다는 연락(ACK)이 안 옵니다.
- 고민: "분실된 건가? 아니면 아직 가는 중인가? 하나 더 보낼까 말까?"
이때 **"평소에 서울-부산 왕복하는 데 얼마나 걸리는지(RTT)"**를 알아야 판단할 수 있습니다.
1. RTT를 모르면 생기는 일 (망함)
- 타이머를 너무 짧게 잡으면:
- 택배가 아직 가고 있는데(5시간 걸림), 성격이 급해서 1시간 만에 "안 왔네? 분실이다!" 하고 또 보냅니다.
- 결과: 멀쩡한 택배가 2개 도착함. (낭비)
- 타이머를 너무 길게 잡으면:
- 택배는 1시간 만에 분실됐는데, 넉넉하게 잡는답시고 100시간을 기다립니다.
- 결과: 100시간 동안 아무것도 안 하고 멍때림. (속도 저하)
2. RTT를 알면 생기는 일 (성공)
- "평소에 갔다 오는 데 10시간(RTT) 걸리더라."
- "그럼 난 딱 **12시간(타이머)**만 기다려보고, 그때까지 안 오면 재전송해야지!"
- 결과: 낭비도 없고, 멍때리는 시간도 최소화할 수 있습니다.
[최종 로드맵 복기]
우리가 지금까지 달려온 길은 이렇습니다.
- 목표: 신뢰성 있는 전송을 하고 싶다. (TCP의 목적)
- 방법: 안 오면 다시 보내자. (ARQ / 재전송)
- 도구: 재전송하려면 **타이머(Timer)**가 필요하다.
- 문제: 타이머를 몇 초로 맞춰야 할까?
- 해결: 갔다 오는 시간인 RTT를 재보자.
- 디테일: 근데 RTT가 너무 들쭉날쭉하네? -> **공식(EWMA)**을 써서 평균을 내자.
결론:
RTT 공식이 나오는 이유는 **"타이머를 기가 막히게 적절한 시간으로 세팅해서, 재전송을 똑똑하게 하기 위함"**입니다.
**"아직 숨이 붙어있는가, 아니면 완전히 죽었는가?"**의 차이입니다.
교수님이 녹음본에서 말씀하신 논리를 아주 쉽게 풀어드리면 다음과 같습니다.
1. 3중복 ACK (3 Duplicate ACKs) = "가벼운 증상 (Less Serious)"
"한 놈만 재수 없어서 넘어진 거고, 나머지는 잘 달리고 있다."
- 상황: 2번 패킷이 손실됐는데, 뒤따라간 3, 4, 5번 패킷은 도착했습니다.
- 증거: 수신자가 **"야! 2번 안 왔어(ACK 2)"**라고 계속 외칩니다.
- 해석:
- 송신자는 생각합니다. "ACK가 계속 온다는 건, 네트워크가 끊기지는 않았다는 뜻이네?"
- "내가 보낸 3, 4, 5번이 잘 도착했다는 거잖아."
- "그럼 네트워크가 꽉 막힌 건 아니고, 그냥 2번 쟤만 재수 없어서 빠진 거구나."
- 결과: 굳이 속도를 1로 줄일 필요는 없다. 절반(1/2)만 줄이자. (TCP Reno)
2. 타임아웃 (Timeout) = "심각한 증상 (Serious)"
"도로가 끊겼다. 아무도 살아서 돌아오지 못한다."
- 상황: 2번도 안 오고, 뒤따라간 3, 4, 5번도 아무 소식이 없습니다.
- 증거: 침묵(Silence). 아무런 ACK도 오지 않고 결국 기나긴 타이머가 터집니다.
- 해석:
- 송신자는 생각합니다. "뒤에 보낸 패킷들도 하나도 도착을 안 했나 보네?"
- "ACK가 하나도 안 오는 걸 보니, 이건 도로 자체가 붕괴됐거나 꽉 막혀서 아예 통신 불능 상태구나."
- "지금 데이터를 더 보내면 위험하다."
- 결과: 비상사태 선포. 속도를 1(바닥)로 초기화하고 처음부터 조심스럽게 다시 시작하자. (TCP Tahoe/Reno 공통)
[시험용 핵심 비교]
| 구분 | 3 중복 ACK (3 Dup ACKs) | 타임아웃 (Timeout) |
| 네트워크 상태 | 소통 원활함. (뒤에 보낸 패킷들은 잘 도착해서 ACK를 보내줌) | 꽉 막힘/단절. (뒤에 보낸 패킷들도 다 죽어서 ACK가 아예 안 옴) |
| 비유 | 택배 트럭에서 상자 하나가 떨어진 상황. | 택배 트럭이 절벽 아래로 추락한 상황. |
| 판단 | 경미한 혼잡 (Loss) | 심각한 혼잡 (Severe Congestion) |
| 조치 (Reno) | 속도를 절반으로 줄임 (Fast Recovery) | 속도를 1로 줄임 (Slow Start) |
[결론]
"ACK가 돌아온다"는 건 어쨌든 데이터가 흐르고 있다는 증거이므로 덜 심각하게 보고, "ACK조차 안 온다"는 건 흐름이 멈췄다는 뜻이므로 심각하게 보는 것입니다.
녹음본의 설명과 네트워크 이론을 합쳐서, 왜 min 함수를 쓰는지, 그리고 속도 공식은 왜 저렇게 나오는지 명쾌하게 정리해 드릴게요.
시험에 서술형으로 나오면 **"두 가지 제어(흐름/혼잡)를 동시에 만족해야 하기 때문"**이라고 쓰시면 됩니다.
1. min(cwnd, rwnd)의 의미: "두 상사의 눈치를 다 봐야 한다"
송신자(보내는 사람)는 데이터를 보낼 때 **두 가지 걱정거리(제약 조건)**가 있습니다.
- 네트워크 걱정 (cwnd): "길이 막히나? 너무 많이 보내면 네트워크가 터질까?" (Congestion Control)
- 수신자 걱정 (rwnd): "쟤가 다 받을 수 있나? 너무 많이 보내면 수신자가 토할까?" (Flow Control)
녹음본의 설명 (해석)
교수님이 **"리시브 윈도우(rwnd)하고 컨제스천 윈도우(cwnd)하고 두 개를 비교해서 작은 것만큼만 때려 붓습니다"**라고 하셨죠?
- 상황 A (네트워크는 뻥 뚫렸는데 수신자가 바쁨):
- cwnd = 1000 (길 넓음)
- rwnd = 10 (수신자 배부름)
- 결과: 1000개를 보내면 수신자가 990개를 버려야 합니다. -> 10개만 보냄 (min 선택)
- 상황 B (수신자는 널널한데 네트워크가 막힘):
- cwnd = 10 (길 막힘)
- rwnd = 1000 (수신자 배고픔)
- 결과: 1000개를 보내면 길에서 다 사고 납니다. -> 10개만 보냄 (min 선택)
[결론]
송신자는 **네트워크(혼잡 제어)**와 수신자(흐름 제어) 중 **더 상황이 안 좋은 쪽(엄격한 쪽, 작은 값)**에 맞춰야 사고가 안 납니다. 그래서 min을 씁니다.
2. rate = cwnd / RTT의 의미: "한 텀에 얼마나 보내나?"
이 공식은 복잡한 미적분이 아니라, 속도 = 거리 / 시간 같은 단순한 물리 공식입니다.
녹음본의 설명 (해석)
교수님이 **"송신 버퍼 사이즈(cwnd)만큼 쫙 때려 붓고, 그게 ACK 되어 돌아오는 데 걸리는 시간이 RTT니까... 대충 이렇게 쓸 수 있다"**라고 하셨죠.
- 보내는 양 (cwnd):
- TCP는 ACK를 기다리지 않고 윈도우 크기만큼 와장창 보낼 수 있습니다.
- 즉, 한 번 턴(Turn)을 돌 때 cwnd 바이트만큼 데이터를 쏟아냅니다.
- 걸리는 시간 (RTT):
- 그 데이터를 다 보내고, 상대방이 "잘 받았어"라고 확인(ACK)해줘서, 내가 다음 데이터를 보낼 수 있게 될 때까지 걸리는 시간이 대충 **RTT(왕복 시간)**입니다.
- 속도 계산:
- 속도(Rate) = 보낸 양 / 걸린 시간
- Rate = cwnd / RTT
[시험용 요약]
- 의미: TCP의 전송 속도는 윈도우 크기에 비례하고, **왕복 시간(RTT)**에 반비례한다.
- 주의: 교수님이 **"근사적으로(대충)"**라고 하신 이유는, 실제로는 패킷을 밀어 넣는 시간(Transmission Time)도 있지만, RTT가 워낙 기니까 무시하고 단순화했기 때문입니다.
[최종 정리]
- 왜 min인가?
- **수신자 보호(rwnd)**와 **네트워크 보호(cwnd)**를 동시에 하려다 보니, 둘 중 **더 작은 값(더 빡빡한 조건)**을 따라야 하기 때문.
- 왜 cwnd / RTT인가?
- RTT(한 주기) 동안 보낼 수 있는 최대 데이터 양이 윈도우 크기(cwnd)이기 때문. (속도 = 양 / 시간)

**Sequence Number(순서 번호)**와 **Ack Number(확인 응답 번호)**가 에러 컨트롤(ARQ)의 핵심인 이유는 "무엇이 사라졌는지, 무엇을 다시 보내야 하는지"를 식별하는 유일한 기준이기 때문입니다.
ARQ(Automatic Repeat reQuest)는 말 그대로 **"자동으로(Automatic) 다시 보내달라고(Repeat) 요청(Request)"**하는 시스템인데, 번호표가 없으면 이 과정 자체가 불가능합니다.
쉽게 이해할 수 있도록 3가지 핵심 이유로 정리해 드립니다.
1. 분실된 패킷을 감지하기 위해 (Loss Detection)
데이터가 인터넷을 돌아다니다 보면 중간에 사라질(Loss) 수 있습니다. 번호가 없다면 사라진 사실조차 모릅니다.
- 번호가 없을 때:
- 송신자: "안녕", "밥 먹었니?", "잘 자" (보냄)
- 수신자: "안녕", "잘 자" (받음) -> 중간에 말이 빠졌는데, 원래 그런 문장인 줄 알고 넘어감. (오류 감지 실패)
- 번호가 있을 때 (Sequence Number):
- 송신자: "1.안녕", "2.밥 먹었니?", "3.잘 자"
- 수신자: "1.안녕", "3.잘 자" -> "어? 1번 다음에 3번이 왔네? 2번이 사라졌구나!" (오류 감지 성공)
2. 구체적으로 무엇을 다시 보낼지 알리기 위해 (Retransmission)
오류가 났다는 걸 알았다면, 송신자에게 **"딱 그것만 다시 보내줘"**라고 말해야 합니다. 이때 Ack Number가 사용됩니다.
- 번호가 없을 때:
- 수신자: "야, 중간에 뭔가 빠졌어! 다시 보내!"
- 송신자: "뭐가 빠졌는데? 처음부터 다 다시 보내야 해?" -> 비효율적
- 번호가 있을 때 (Ack Number):
- 수신자: (2번이 안 온 걸 보고) "나 2번 못 받았어(NACK 2)" 또는 **"나 1번까지만 받았어(ACK 2 Request)"**라고 말함.
- 송신자: "아, 2번만 다시 보내주면 되는구나." -> 효율적인 에러 복구(ARQ)
3. 중복된 패킷을 걸러내기 위해 (Duplicate Control)
네트워크가 불안정하면 송신자가 패킷을 보냈는데, 수신자의 ACK가 늦게 도착해서 송신자가 "안 갔나?" 하고 똑같은 걸 또 보낼 때가 있습니다.
- 번호가 없을 때:
- 수신자: "결제해줘", "결제해줘" -> 두 번 결제해버림 (심각한 오류)
- 번호가 있을 때:
- 수신자: "100.결제해줘", "100.결제해줘" -> "어? 100번 아까 처리했는데 또 왔네? 뒤에 건 버려야지." (오류 제어)
요약: ARQ와의 관계
ARQ 프로토콜(Stop-and-Wait, Go-Back-N, Selective Repeat)이 작동하려면 다음 대화가 가능해야 합니다.
"너 3번까지 잘 받았니? (Seq)"
"응, 3번까지 잘 받았고 4번 보내줘. (Ack)"
"어? 4번 보냈는데 답이 없네? 4번 재전송할게. (Time-out & Retransmission)"
이 대화에서 3번, 4번이라는 **번호(Seq/Ack)**가 없으면 대화 자체가 성립이 안 됩니다. 그래서 Seq/Ack가 에러 컨트롤(ARQ)의 필수 요소인 것입니다.

**"인터넷은 양방향 통신(Full-Duplex)이기 때문"**입니다. 이게 가장 결정적인 이유입니다.
더 쉽게 말하면, 내가 보낸 데이터의 번호와 내가 받은 데이터의 번호는 서로 완전히 별개의 카운트이기 때문에 칸이 두 개가 필요한 것입니다.
이해를 돕기 위해 A와 B가 서로 대화하는 상황을 예로 들어 설명해 드릴게요.
1. 서로 다른 두 개의 "말(Data) 줄기"
TCP 연결에서는 A만 말하고 B는 듣기만 하는 게 아닙니다. A도 말을 하고, 동시에 B도 말을 합니다.
- 줄기 1 (A → B): A가 보내는 데이터 (A가 영화 파일을 보냄)
- 줄기 2 (B → A): B가 보내는 데이터 (B가 채팅 메시지를 보냄)
이 두 줄기는 서로 상관없이 독립적으로 흘러갑니다. A는 100만 번째 데이터를 보내고 있는데, B는 이제 막 50번째 데이터를 보내고 있을 수도 있죠.
2. 한 패킷 안에서 두 가지 일을 동시에 처리 (Piggybacking)
A가 B에게 패킷을 하나 보낼 때, TCP는 효율성을 위해 두 가지 말을 한 번에 담아서 보냅니다.
"야 B야, (1) 이건 내가 보내는 100번째 데이터야. 그리고 (2) 네가 보낸 건 50번까지 잘 받았어."
이 한 문장을 해석해 보면:
- (1) "내가 보내는 100번째 데이터야" Sequence Number (나의 말)
- 이건 내 데이터의 순서를 알리는 번호입니다.
- →\rightarrow
- (2) "네가 보낸 건 50번까지 잘 받았어" Acknowledgment Number (너의 말에 대한 대답)
- 이건 상대방 데이터를 어디까지 받았는지 알리는 번호입니다.
- →\rightarrow
3. 만약 칸이 하나(Sequence Number)만 있다면?
만약 헤더에 번호 적는 칸이 하나밖에 없다고 가정해 봅시다.
- A가 패킷을 보낼 때 그 칸에 100이라고 적었습니다.
- B가 이걸 받으면 헷갈립니다.
- "이 100이 자기가 보낸 데이터가 100번이라는 소리야? (Seq)"
- "아니면 내 거 100번까지 잘 받았다는 소리야? (Ack)"
두 정보는 전혀 다른 의미이고 값도 다르기 때문에, 절대 하나의 칸으로 퉁칠 수가 없습니다.
요약
TCP 헤더에 두 칸이 모두 있는 이유는 **"내 입(Seq)과 내 귀(Ack)가 동시에 작동하기 때문"**입니다.
- Sequence Number: [내 입] "내가 지금 보내는 이 데이터는 X번째 조각이야." (내 데이터 관리)
- Acknowledgment Number: [내 귀] "네가 보낸 데이터는 Y번까지 잘 들었어." (상대방 데이터 관리)
이 두 가지를 한 패킷에 담아서 서로 주고받아야(Piggybacking) 가장 효율적이기 때문에 두 필드가 모두 필수적입니다.
'25년2학기 > 컴퓨터 네트워크' 카테고리의 다른 글
| 컴넷) (12.05) (1) | 2025.12.05 |
|---|---|
| 컴넷) 시험문제 (12.05) (0) | 2025.12.05 |
| 컴넷) (11.30) (1) | 2025.11.30 |
| 컴넷) (11.28) (0) | 2025.11.28 |
| 컴넷) (11.26) (0) | 2025.11.26 |