<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://minjune8506.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://minjune8506.github.io/" rel="alternate" type="text/html" /><updated>2026-08-11T16:34:16+00:00</updated><id>https://minjune8506.github.io/feed.xml</id><title type="html">뇌절</title><subtitle>굳이 여기까지 알 필요는 없지만, 재미로 밑바닥까지 파보는 기술 블로그</subtitle><author><name>minjune8506</name></author><entry><title type="html">TCP란 무엇인가</title><link href="https://minjune8506.github.io/posts/2026/08/14/tcp-01-what-is-tcp/" rel="alternate" type="text/html" title="TCP란 무엇인가" /><published>2026-08-14T00:00:00+00:00</published><updated>2026-08-14T00:00:00+00:00</updated><id>https://minjune8506.github.io/posts/2026/08/14/tcp-01-what-is-tcp</id><content type="html" xml:base="https://minjune8506.github.io/posts/2026/08/14/tcp-01-what-is-tcp/"><![CDATA[<p><strong>뇌절</strong>의 첫 시리즈 주제, TCP입니다. <a href="/posts/2026/08/13/tcp-series-roadmap/">로드맵</a>에서 예고한 대로, 이번 글은 기본 단계의 첫 번째 글이라 아주 기초적인 질문부터 시작합니다: <strong>TCP가 정확히 뭘 하는 프로토콜인가?</strong></p>

<h2 id="tcp는-어디에-있는가">TCP는 어디에 있는가</h2>

<p>인터넷에서 데이터를 주고받을 때, 여러 계층이 각자 역할을 나눠 맡습니다. TCP/IP 4계층 모델로 보면 이렇습니다.</p>

<figure class="post-figure">
<svg viewBox="0 0 640 370" role="img" aria-label="TCP/IP 4계층 구조. Application 계층 아래 Transport 계층이 있고, Transport 계층 안에 TCP와 UDP가 나란히 있다. 그 아래 Internet 계층(IP), 가장 아래 Link 계층이 있다." xmlns="http://www.w3.org/2000/svg">
  <rect x="40" y="20" width="560" height="64" fill="none" stroke="currentColor" stroke-width="1.5" rx="4" />
  <text x="60" y="58" font-size="14" font-weight="600" fill="currentColor" font-family="sans-serif">Application 계층</text>
  <text x="580" y="58" font-size="12" fill="currentColor" fill-opacity="0.6" font-family="sans-serif" text-anchor="end">HTTP · DNS · SSH ...</text>

  <rect x="40" y="98" width="560" height="100" fill="none" stroke="currentColor" stroke-width="1.5" rx="4" />
  <text x="60" y="118" font-size="14" font-weight="600" fill="currentColor" font-family="sans-serif">Transport 계층</text>

  <rect x="60" y="130" width="250" height="54" fill="none" stroke="var(--tcp-accent)" stroke-width="2.5" rx="4" />
  <text x="185" y="153" font-size="16" font-weight="700" fill="var(--tcp-accent)" font-family="sans-serif" text-anchor="middle">TCP</text>
  <text x="185" y="171" font-size="10" fill="var(--tcp-accent)" fill-opacity="0.85" font-family="sans-serif" text-anchor="middle">연결지향 · 신뢰성 — 이 시리즈의 주제</text>

  <rect x="330" y="130" width="250" height="54" fill="none" stroke="currentColor" stroke-width="1.5" rx="4" />
  <text x="455" y="153" font-size="16" font-weight="700" fill="currentColor" font-family="sans-serif" text-anchor="middle">UDP</text>
  <text x="455" y="171" font-size="10" fill="currentColor" fill-opacity="0.6" font-family="sans-serif" text-anchor="middle">비연결 · 빠름</text>

  <rect x="40" y="212" width="560" height="64" fill="none" stroke="currentColor" stroke-width="1.5" rx="4" />
  <text x="60" y="250" font-size="14" font-weight="600" fill="currentColor" font-family="sans-serif">Internet 계층</text>
  <text x="580" y="250" font-size="12" fill="currentColor" fill-opacity="0.6" font-family="sans-serif" text-anchor="end">IP</text>

  <rect x="40" y="290" width="560" height="64" fill="none" stroke="currentColor" stroke-width="1.5" rx="4" />
  <text x="60" y="328" font-size="14" font-weight="600" fill="currentColor" font-family="sans-serif">Link 계층</text>
  <text x="580" y="328" font-size="12" fill="currentColor" fill-opacity="0.6" font-family="sans-serif" text-anchor="end">Ethernet · Wi-Fi ...</text>
</svg>
<figcaption>TCP는 Transport 계층에서 UDP와 나란히 동작하며, Internet 계층(IP) 위에 얹혀서 돈다.</figcaption>
</figure>

<p>여기서 두 가지만 기억하면 됩니다.</p>

<ol>
  <li><strong>TCP는 IP 위에서 동작한다.</strong> “TCP/IP”라는 이름 자체가 이 관계를 말해줍니다. IP는 “어디로 보낼지(주소)”만 책임지고, 그 패킷이 가는 중에 사라지든 순서가 뒤바뀌든 신경 쓰지 않습니다. 그 위에서 “확실하게, 순서대로” 보내는 역할을 TCP가 맡습니다.</li>
  <li><strong>Transport 계층에는 TCP만 있는 게 아니다.</strong> 같은 자리에 UDP도 있습니다. 둘은 같은 문제(애플리케이션 간에 데이터를 주고받는 것)를 완전히 다른 방식으로 풉니다. 이 차이가 이 글의 핵심입니다.</li>
</ol>

<h2 id="연결지향과-신뢰성이-구체적으로-뭔가">“연결지향”과 “신뢰성”이 구체적으로 뭔가</h2>

<p>TCP를 설명할 때 항상 따라붙는 두 단어가 “연결지향(connection-oriented)”과 “신뢰성 있는(reliable)”입니다. 각각 구체적으로 무슨 뜻인지 뜯어보겠습니다.</p>

<ul>
  <li><strong>연결지향</strong>: 데이터를 보내기 전에 먼저 양쪽이 “연결”이라는 상태를 만듭니다. 이 상태가 있어야만 데이터를 주고받을 수 있고, 다 끝나면 명시적으로 연결을 끊습니다. (연결을 어떻게 맺는지는 3편에서 다룹니다.)</li>
  <li><strong>신뢰성</strong>: 보낸 데이터가 상대방에게 순서대로, 빠짐없이 도착했다는 걸 보장합니다. 중간에 유실되면 다시 보내고, 순서가 뒤바뀌어 도착해도 원래 순서로 재조립해줍니다. (구체적인 방법은 4~5편에서 다룹니다.)</li>
</ul>

<p>UDP는 이 둘 다 하지 않습니다. 연결이라는 개념 자체가 없고, 보낸 데이터가 도착했는지도 UDP 스스로는 신경 쓰지 않습니다. 그림으로 비교하면 이렇습니다.</p>

<figure class="post-figure">
<svg viewBox="0 0 640 130" role="img" aria-label="TCP는 Client와 Server가 연결을 맺고 유지하며 데이터를 주고받는다. UDP는 연결 없이 각 패킷을 독립적으로 전송한다." xmlns="http://www.w3.org/2000/svg">
  <defs>
    <marker id="tcp01-arrow-accent" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
      <path d="M0,0 L10,5 L0,10 z" fill="var(--tcp-accent)" />
    </marker>
    <marker id="tcp01-arrow-plain" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
      <path d="M0,0 L10,5 L0,10 z" fill="currentColor" />
    </marker>
  </defs>

  <text x="155" y="18" font-size="13" font-weight="600" fill="var(--tcp-accent)" font-family="sans-serif" text-anchor="middle">TCP — 연결지향</text>
  <rect x="30" y="46" width="90" height="40" fill="none" stroke="currentColor" stroke-width="1.5" rx="4" />
  <text x="75" y="70" font-size="13" fill="currentColor" font-family="sans-serif" text-anchor="middle">Client</text>
  <rect x="190" y="46" width="90" height="40" fill="none" stroke="currentColor" stroke-width="1.5" rx="4" />
  <text x="235" y="70" font-size="13" fill="currentColor" font-family="sans-serif" text-anchor="middle">Server</text>
  <line x1="122" y1="66" x2="188" y2="66" stroke="var(--tcp-accent)" stroke-width="4" marker-start="url(#tcp01-arrow-accent)" marker-end="url(#tcp01-arrow-accent)" />
  <text x="155" y="112" font-size="11" fill="currentColor" fill-opacity="0.75" font-family="sans-serif" text-anchor="middle">연결을 맺고 유지하며 데이터 교환</text>

  <text x="480" y="18" font-size="13" font-weight="600" fill="currentColor" fill-opacity="0.85" font-family="sans-serif" text-anchor="middle">UDP — 비연결</text>
  <rect x="350" y="46" width="90" height="40" fill="none" stroke="currentColor" stroke-width="1.5" rx="4" />
  <text x="395" y="70" font-size="13" fill="currentColor" font-family="sans-serif" text-anchor="middle">Client</text>
  <rect x="510" y="46" width="90" height="40" fill="none" stroke="currentColor" stroke-width="1.5" rx="4" />
  <text x="555" y="70" font-size="13" fill="currentColor" font-family="sans-serif" text-anchor="middle">Server</text>
  <line x1="442" y1="54" x2="508" y2="54" stroke="currentColor" stroke-width="1.5" marker-end="url(#tcp01-arrow-plain)" />
  <line x1="442" y1="66" x2="508" y2="66" stroke="currentColor" stroke-width="1.5" marker-end="url(#tcp01-arrow-plain)" />
  <line x1="442" y1="78" x2="508" y2="78" stroke="currentColor" stroke-width="1.5" marker-end="url(#tcp01-arrow-plain)" />
  <text x="480" y="112" font-size="11" fill="currentColor" fill-opacity="0.75" font-family="sans-serif" text-anchor="middle">그때그때 독립적으로 전송 (연결 없음)</text>
</svg>
<figcaption>TCP는 연결을 유지한 채로 데이터를 주고받고, UDP는 연결이라는 상태 없이 패킷을 독립적으로 보낸다.</figcaption>
</figure>

<p>UDP 쪽 화살표 3개가 서로 이어져 있지 않다는 점이 중요합니다. 각 패킷은 서로 아무 관계가 없습니다. 하나가 중간에 사라져도 UDP는 그걸 모르고, 순서가 뒤바뀌어 도착해도 신경 쓰지 않습니다. 그 대신 “연결을 맺고 유지하는” 오버헤드가 없어서 더 가볍고 빠릅니다.</p>

<h2 id="tcp-vs-udp">TCP vs UDP</h2>

<table>
  <thead>
    <tr>
      <th> </th>
      <th>TCP</th>
      <th>UDP</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>연결</td>
      <td>연결지향 (핸드셰이크 필요)</td>
      <td>비연결</td>
    </tr>
    <tr>
      <td>신뢰성</td>
      <td>순서 보장, 유실 시 재전송</td>
      <td>보장 없음</td>
    </tr>
    <tr>
      <td>속도</td>
      <td>상대적으로 느림 (연결 유지·재전송 비용)</td>
      <td>빠름</td>
    </tr>
    <tr>
      <td>오버헤드</td>
      <td>큼 (헤더 20바이트, 상태 관리)</td>
      <td>작음 (헤더 8바이트)</td>
    </tr>
    <tr>
      <td>대표 사용처</td>
      <td>웹(HTTP), 파일 전송, 이메일 — “틀리면 안 되는” 데이터</td>
      <td>실시간 스트리밍, 온라인 게임, DNS — “늦으면 의미 없는” 데이터</td>
    </tr>
  </tbody>
</table>

<p>이 표에서 가장 중요한 건 “TCP가 항상 더 좋다”가 아니라는 겁니다. 실시간 음성 통화에서는 0.5초 전 패킷이 지금 도착해서 재생되는 것보다, 그냥 버리고 최신 패킷을 트는 게 낫습니다. TCP가 유실된 패킷을 재전송하려고 애쓰는 동안 통화는 이미 끊긴 것처럼 느껴집니다. 그래서 이런 경우엔 UDP를 씁니다. 반대로 파일 하나를 내려받는데 중간 바이트 몇 개가 빠지면 파일 자체가 깨지므로, 이런 경우엔 반드시 TCP를 씁니다.</p>

<h2 id="이-시리즈에서-쓸-용어">이 시리즈에서 쓸 용어</h2>

<p>앞으로 자주 나올 단어 세 개를 미리 정리합니다.</p>

<ul>
  <li><strong>세그먼트(segment)</strong>: TCP가 주고받는 데이터 단위. (IP 계층에서는 이걸 “패킷”, Link 계층에서는 “프레임”이라고 부릅니다. 같은 데이터를 계층마다 다르게 부르는 것뿐입니다.)</li>
  <li><strong>연결(connection)</strong>: 3-way handshake로 맺어지고 4-way handshake로 끊어지는, 두 endpoint 사이의 상태. TCP의 모든 동작은 이 연결이 있다는 걸 전제로 합니다.</li>
  <li><strong>스트림(stream)</strong>: TCP가 애플리케이션에 제공하는 추상화. 애플리케이션 입장에서 TCP는 “세그먼트를 여러 개 주고받는 것”이 아니라 “끊김 없는 바이트의 흐름”처럼 보입니다. 이 스트림 추상화 뒤에서 세그먼트 분할, 재조립, 재전송이 전부 숨겨져 있습니다.</li>
</ul>

<h2 id="다음-글">다음 글</h2>

<p>지금까지는 “TCP가 뭘 하는가”를 큰 그림으로만 봤습니다. 다음 글에서는 “같은 컴퓨터에서 여러 프로그램이 동시에 TCP를 쓰면 어떻게 구분하는가” — 포트와 소켓 이야기로 넘어갑니다.</p>]]></content><author><name>minjune8506</name></author><category term="TCP" /><category term="뇌절" /><category term="TCP" /><category term="기본" /><summary type="html"><![CDATA[뇌절의 첫 시리즈 주제, TCP입니다. 로드맵에서 예고한 대로, 이번 글은 기본 단계의 첫 번째 글이라 아주 기초적인 질문부터 시작합니다: TCP가 정확히 뭘 하는 프로토콜인가?]]></summary></entry><entry><title type="html">TCP 뇌절 시리즈: 로드맵</title><link href="https://minjune8506.github.io/posts/2026/08/13/tcp-series-roadmap/" rel="alternate" type="text/html" title="TCP 뇌절 시리즈: 로드맵" /><published>2026-08-13T01:00:00+00:00</published><updated>2026-08-13T01:00:00+00:00</updated><id>https://minjune8506.github.io/posts/2026/08/13/tcp-series-roadmap</id><content type="html" xml:base="https://minjune8506.github.io/posts/2026/08/13/tcp-series-roadmap/"><![CDATA[<p><strong>뇌절</strong>의 첫 시리즈 주제는 TCP입니다. 다만 “뇌절”이라고 해서 처음부터 커널 코드나 RFC로 들어가지는 않습니다.</p>

<p>이 시리즈는 <strong>기본 → 심화 → 뇌절</strong> 3단계로 이어집니다. 순서대로 읽으면 중간에 끊기는 곳 없이 이해할 수 있도록, 각 글은 바로 앞 글에서 다룬 내용을 전제로 삼고 다음 글로 넘어갈 다리를 명시적으로 놓습니다.</p>

<ul>
  <li><strong>기본</strong>: 누구나 알아야 할, 그리고 알면 충분한 TCP. “TCP를 쓰는 사람” 레벨.</li>
  <li><strong>심화</strong>: 기본편에서 “그냥 그렇다”고 넘어간 것들을 RFC 원문과 Linux 커널 코드로 검증. “TCP를 다루는 엔지니어” 레벨.</li>
  <li><strong>뇌절</strong>: 이론을 손으로 직접 재현. 패킷을 직접 만들고, 상태머신을 직접 구현하고, 혼잡제어를 직접 시뮬레이션. 그리고 여기서부터는 사실 몰라도 되는 것들까지 재미로 계속 팝니다.</li>
</ul>

<p>마지막 단계 이름이 시리즈 이름과 같은 건 우연이 아닙니다.</p>

<h2 id="확정-연재-19편">확정 연재 (19편)</h2>

<p>매주 하나씩, 아래 순서로 발행합니다.</p>

<h3 id="기본--tcp를-쓰는-사람이면-충분한-레벨">기본 — TCP를 쓰는 사람이면 충분한 레벨</h3>
<ol>
  <li>TCP란 무엇인가</li>
  <li>포트와 소켓 — 연결을 식별하는 방법</li>
  <li>연결 수립 — 3-way handshake</li>
  <li>데이터 전송과 흐름제어</li>
  <li>신뢰성 보장 — ACK와 재전송</li>
  <li>혼잡제어, 큰 그림</li>
  <li>연결 종료 — 4-way handshake와 TIME_WAIT</li>
</ol>

<h3 id="심화--기본편의-왜를-스펙과-커널-코드로-검증">심화 — 기본편의 “왜”를 스펙과 커널 코드로 검증</h3>
<ol>
  <li>RFC 793 vs RFC 9293, 뭐가 왜 바뀌었나</li>
  <li>TCP 헤더 32비트 완전분해</li>
  <li>시퀀스 넘버 wraparound과 PAWS (RFC 1323)</li>
  <li>Linux TCP 상태머신, 소스로 따라가기</li>
  <li>소켓 버퍼·재전송 큐·RTO 계산의 실제 구현</li>
  <li>혼잡제어: Reno vs Cubic vs BBR 커널 코드 비교</li>
  <li>strace로 소켓 syscall 흐름 추적하기</li>
  <li>NIC 오프로딩(TSO/GRO)과 epoll 내부 구현</li>
</ol>

<h3 id="뇌절--직접-만들어서-확인">뇌절 — 직접 만들어서 확인</h3>
<ol>
  <li>Wireshark로 핸드셰이크 패킷 뜯어서 RFC와 대조하기</li>
  <li>Raw socket으로 TCP 패킷 직접 만들기</li>
  <li>미니 TCP 상태머신 직접 구현하고 실제 커널과 비교</li>
  <li>혼잡제어 알고리즘을 시뮬레이션 코드로 구현해 처리량 비교</li>
</ol>

<h2 id="번외-뇌절-내킬-때만">번외 뇌절 (내킬 때만)</h2>

<p>19편까지 다 읽고 나면 사실 TCP를 이해하는 데 더 필요한 건 없습니다. 그래도 재미로 계속 팝니다. 매주 연재 약속은 없고, 필받을 때 하나씩 추가합니다.</p>

<ul>
  <li><strong>물리 계층</strong>: 케이블 위의 전압 파형, Manchester encoding, PHY 칩 동작</li>
  <li><strong>수학적 증명</strong>: AIMD 공정성 증명(Chiu &amp; Jain, 1989), RTO 공식(Jacobson/Karels, 1988) 유도</li>
  <li><strong>역사 고고학</strong>: Cerf &amp; Kahn 1974년 원논문, OSI vs TCP/IP 표준 전쟁, BSD Sockets 역사</li>
  <li><strong>형식 검증</strong>: TCP 상태머신을 TLA+/Alloy로 명세하고 모델체커로 검증</li>
  <li><strong>대안 우주와 비교</strong>: QUIC은 TCP의 어떤 문제를 다시 설계했나</li>
  <li><strong>하드웨어에 굽기</strong>: FPGA로 미니 TCP/IP 오프로드 엔진 구현</li>
</ul>

<p>이 로드맵은 진행하면서 계속 업데이트합니다.</p>]]></content><author><name>minjune8506</name></author><category term="TCP" /><category term="뇌절" /><category term="로드맵" /><category term="TCP" /><summary type="html"><![CDATA[뇌절의 첫 시리즈 주제는 TCP입니다. 다만 “뇌절”이라고 해서 처음부터 커널 코드나 RFC로 들어가지는 않습니다.]]></summary></entry><entry><title type="html">뇌절을 시작하며</title><link href="https://minjune8506.github.io/posts/2026/08/12/welcome/" rel="alternate" type="text/html" title="뇌절을 시작하며" /><published>2026-08-12T03:00:00+00:00</published><updated>2026-08-12T03:00:00+00:00</updated><id>https://minjune8506.github.io/posts/2026/08/12/welcome</id><content type="html" xml:base="https://minjune8506.github.io/posts/2026/08/12/welcome/"><![CDATA[<p>GitHub Pages와 Jekyll로 <strong>뇌절</strong>을 시작합니다.</p>

<p>‘뇌절’은 궁금한 게 생기면 적당한 선에서 멈추지 않고 밑바닥까지 파고드는 블로그입니다.
사실 거기까지 알 필요는 없을 때가 많지만, 그냥 재미로 한번 끝까지 가보려고 합니다.</p>

<p>앞으로 개발하면서 배운 내용, 트러블슈팅 경험, 그리고 너무 깊게 파버린 것들을 이 공간에 기록할 예정입니다.</p>

<h2 id="새-글-작성-방법">새 글 작성 방법</h2>

<p><code class="language-plaintext highlighter-rouge">_posts</code> 디렉토리에 아래 형식으로 파일을 추가하면 됩니다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>_posts/YYYY-MM-DD-제목.md
</code></pre></div></div>

<p>파일 상단에는 다음과 같은 front matter를 넣어주세요.</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">layout</span><span class="pi">:</span> <span class="s">post</span>
<span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">글</span><span class="nv"> </span><span class="s">제목"</span>
<span class="na">date</span><span class="pi">:</span> <span class="s">YYYY-MM-DD HH:MM:SS +0900</span>
<span class="na">categories</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">카테고리</span><span class="pi">]</span>
<span class="na">tags</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">태그1</span><span class="pi">,</span> <span class="nv">태그2</span><span class="pi">]</span>
<span class="nn">---</span>
</code></pre></div></div>]]></content><author><name>minjune8506</name></author><category term="general" /><category term="intro" /><summary type="html"><![CDATA[GitHub Pages와 Jekyll로 뇌절을 시작합니다.]]></summary></entry></feed>