Home
Explore Uedu
Student Console
Register as Member/Login
(2) In future presentations of the research findings, in addition to the course project website and public presentations, your real name and personal information will not appear in this research report. If you are interested in the research results, we can provide you with an executive summary after the study is completed.
問卷中心
Teacher Console
Course Setup
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

0

Local AI

--

CISOSE26 本地 AI UG26
政治大學 AQI 18 29°C

AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

協定層與 TCP/IP

協定層與 TCP/IP:一封訊息如何穿過半個地球

從分層模型、IP 路由到 TCP 可靠傳輸與壅塞控制,看懂網際網路如何在不可靠的底層上建立可靠的溝通

一封訊息如何穿過半個地球

你在台北用手機按下「傳送」,一張照片在不到一秒鐘內出現在東京朋友的螢幕上。這段旅程中,照片被切成數百個小封包(packet),分別擠進無數條光纖與基地台,可能各走不同路線,甚至有些半路遺失,最後卻能拼回一張完整無缺的圖。沒有任何單一機器知道「整條路」長什麼樣子,卻能準確送達——這不是魔法,而是一套精心設計的協定(protocol)分層在默默運作。

協定就是「溝通的規矩」。兩台素未謀面、作業系統可能完全不同的電腦,之所以能對話,是因為它們都同意遵守同一套規則:什麼時候該說話、訊息怎麼包裝、收到了要怎麼回應。而 TCP/IP 正是支撐整個網際網路(Internet)的這套規矩。

為什麼要分層?

如果讓一台電腦同時操心「電壓訊號怎麼編碼」「資料怎麼不遺失」「網頁內容怎麼呈現」,程式會複雜到無法維護。網路設計者採用了一個經典的工程策略:分層(layering)。每一層只負責一件事,並且只跟上下相鄰的層對話,把細節藏起來只對外提供乾淨的服務。這種「關注點分離(separation of concerns)」讓不同廠商可以各自實作不同層,只要介面一致就能互通。

網路與網際網路概念示意圖

最有名的兩套分層模型是 OSI 七層模型與 TCP/IP 四層模型。OSI 是學術上的參考框架,TCP/IP 則是實際在運作的工程實作。兩者的對應大致如下:

TCP/IP 四層 對應 OSI 層 代表協定 處理的單位
應用層(Application) 應用/表現/會議層 HTTP、DNS、SMTP 訊息(message)
傳輸層(Transport) 傳輸層 TCP、UDP 區段(segment)
網路層(Internet) 網路層 IP、ICMP 封包(packet)
連結層(Link) 資料連結/實體層 Ethernet、Wi-Fi 訊框(frame)

可以把它想成寄一封國際信件:你寫信(應用層),裝進信封寫上收件人地址(傳輸層與網路層),交給郵局,郵局再決定用卡車還是飛機運送(連結層)。你不需要知道飛機怎麼飛,飛機駕駛也不需要讀你的信。

IP 位址與路由:網路世界的門牌

網路層的核心是 IP(Internet Protocol),它負責「定址」與「路由」。每一台連上網路的裝置都有一個 IP 位址(IP address),就像門牌號碼。IPv4 位址是 32 位元,寫成四段十進位數字,如 140.115.103.70;由於 IPv4 位址不到 43 億個早已不夠用,IPv6 把位址擴展到 128 位元,寫成 2001:0db8:85a3::8a2e:0370:7334 這種十六進位形式。

IP 位址通常分成兩部分:網路前綴(network prefix)主機部分(host part)。以 CIDR 標記法 140.115.0.0/16 為例,斜線後的 16 代表前 16 位元是網路前綴,剩下的 16 位元用來區分這個網路內的主機。路由器(router)就是靠比對前綴來決定封包該往哪個方向轉送。

路由(routing) 是一個逐跳(hop-by-hop)的接力過程。你的封包不會一口氣抵達終點,而是被一台又一台路由器轉送。每台路由器查自己的路由表(routing table),找出「往這個目的地,下一步該交給誰」,然後把封包丟出去。沒有任何一台路由器掌握全貌——它只需要知道「下一跳(next hop)」是誰。這種去中心化設計正是網際網路能擴展到全球規模的關鍵。

值得注意的是,IP 本身是盡力而為(best-effort)的:它不保證封包一定送達、不保證順序、不保證不重複。它只負責「盡力把封包丟向正確方向」。可靠性的責任,交給了上面的傳輸層。

TCP vs UDP:兩種傳輸哲學

傳輸層有兩個主角,代表兩種截然不同的設計哲學。

UDP(User Datagram Protocol) 像寄明信片:寫上地址直接丟進郵筒,不確認對方收到、不管順序、不重寄。它的標頭只有 8 位元組,極度輕量,速度快、延遲低。代價是不可靠——封包可能遺失或亂序,由應用層自行處理。

TCP(Transmission Control Protocol) 像掛號信加上電話確認:建立連線、逐一確認、保證順序、遺失重寄。它提供可靠的、有序的、雙向的位元組串流(byte stream),代價是較高的開銷與延遲。

特性 TCP UDP
連線導向 是(先握手)
可靠性 保證送達、重傳 不保證
順序 保證有序 不保證
速度/延遲 較高開銷 輕量快速
典型應用 網頁、檔案傳輸、Email 視訊串流、線上遊戲、DNS 查詢

選擇哪一個取決於需求:你下載一個檔案,少一個位元組就壞了,必須用 TCP;你在看直播,偶爾掉一格畫面無所謂,但卡頓不能忍,那就用 UDP。

三次握手:建立連線的禮貌

TCP 在傳資料前,必須先「打招呼」建立連線,這個過程稱為三次握手(three-way handshake)

客戶端                              伺服器
  |                                   |
  |  ──── SYN (seq=x) ────────────►   |   「我想連線,我的起始序號是 x」
  |                                   |
  |  ◄─── SYN-ACK (seq=y, ack=x+1) ─  |   「好,我的序號是 y,已收到你的 x」
  |                                   |
  |  ──── ACK (ack=y+1) ──────────►   |   「收到你的 y,開始傳資料吧」
  |                                   |
  |  ═══════ 連線建立完成 ═══════════  |

為什麼是三次而非兩次?因為雙方都必須確認「我能傳給你」且「你能傳給我」這兩件事各一次,三次握手剛好讓雙方都確認彼此的收發能力,並交換各自的初始序號(initial sequence number)。對應地,結束連線需要四次揮手(four-way handshake),因為雙向的串流需要各自獨立關閉。

DNS:把名字翻成位址

人類記得住 uedu.tw,卻記不住 140.115.103.70DNS(Domain Name System) 就是網際網路的「電話簿」,負責把好記的網域名稱翻譯成 IP 位址。

DNS 採用階層式的分散架構:當你的電腦想查 www.uedu.tw,它會先問本地的解析器(resolver),解析器再依序詢問根伺服器(知道 .tw 在哪)、頂級網域伺服器(知道 uedu.tw 在哪)、最後是 uedu.tw 的權威伺服器(authoritative server,給出實際 IP)。為了避免每次都跑這一圈,各層都會做快取(cache),所以你第二次造訪同一網站通常會快很多。

DNS 查詢大多走 UDP(因為又小又快),這也呼應了前面 UDP 的應用情境。

封裝:層層包裝的旅程

當資料從應用層往下走,每一層都會在前面加上自己的標頭(header),這個過程稱為封裝(encapsulation);資料抵達對方後再層層拆開,稱為解封裝(decapsulation)

應用層:                           [    HTTP 資料    ]
傳輸層:                  [ TCP標頭 |   HTTP 資料    ]
網路層:        [ IP標頭 | TCP標頭 |   HTTP 資料    ]
連結層:  [訊框標頭| IP標頭 | TCP標頭 |   HTTP 資料  |訊框尾]

像一個一個套上去的信封:最內層是你要說的話,每往外一層就多一層收件資訊。對方收到後從最外層開始拆,每一層讀完屬於自己的標頭就交給上一層。每一層只看自己的標頭,不去動內層的內容——這正是分層設計的優雅之處。

動手看一個例子

讓我們用 Python 觀察一次最樸素的傳輸層通訊。下面用 socket 建立一個 TCP 連線並送出 HTTP 請求,看看「位元組串流」實際長什麼樣:

import socket

# 建立 TCP socket:AF_INET 表示 IPv4,SOCK_STREAM 表示 TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# connect 這一步在底層就觸發了三次握手
s.connect(("example.com", 80))

# 送出一段最簡單的 HTTP 請求(應用層訊息)
request = "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n"
s.sendall(request.encode("utf-8"))

# 接收回應:TCP 是串流,可能要多次 recv 才收完
response = b""
while True:
    chunk = s.recv(4096)
    if not chunk:          # 收到空字串代表對方關閉連線
        break
    response += chunk

s.close()
print(response.decode("utf-8", errors="ignore")[:200])

幾個關鍵觀察:第一,SOCK_STREAM 就是在選擇 TCP(若改成 SOCK_DGRAM 就是 UDP)。第二,connect() 背後自動完成了三次握手,我們完全不用手動處理序號。第三,那個 while 迴圈很重要——因為 TCP 是串流而非「一封一封的訊息」,作業系統可能把資料分好幾次交給我們,必須持續讀到對方關閉為止。這正體現了 TCP「位元組串流」的本質:它保證所有位元組依序到齊,但不替你劃分訊息邊界,那是應用層的責任。

重點回顧

  • 網路用分層化解複雜度:應用層管內容、傳輸層管可靠、網路層管定址路由、連結層管實體傳送,每層只跟相鄰層對話。
  • IP 提供盡力而為的定址與逐跳路由;位址分為網路前綴與主機部分,路由器靠比對前綴決定下一跳。
  • TCP 可靠有序但開銷大,UDP 輕量快速但不保證;選擇取決於「正確性」與「即時性」孰輕孰重。
  • 三次握手讓雙方互相確認收發能力並交換初始序號,才開始傳資料。
  • DNS 把網域名稱翻成 IP,採階層式架構並大量使用快取;封裝讓資料層層加上標頭再層層拆解。

深入探討(研究所視角)

前面說 TCP「可靠」,但 IP 底層明明是不可靠的——TCP 究竟如何在沙地上蓋出穩固的高樓?答案藏在四個彼此交織的機制裡。

序號(sequence number)與 ACK。 TCP 替送出的每一個位元組編號。接收端透過累積確認(cumulative ACK) 回報「我已連續收到第 N 號之前的所有位元組,請從 N 開始給我」。這個設計讓接收端能重組亂序到達的封包,並偵測缺漏。現代 TCP 多半還支援選擇性確認(SACK, Selective ACK),能告知「我收到了 1–100 與 200–300,但中間 101–199 不見了」,避免重傳已收到的區段。

重傳(retransmission)。 偵測遺失有兩條路。其一是逾時重傳(RTO, Retransmission Timeout):送出後啟動計時器,逾時未收到 ACK 就重送。RTO 由動態估計的往返時間(RTT)推算,常用 Jacobson 演算法以平滑 RTT 與其變異量計算:

$$\text{RTO} = \text{SRTT} + 4 \times \text{RTTVAR}$$

其二是快速重傳(fast retransmit):當送端連續收到 3 個重複 ACK(duplicate ACK),不必等計時器逾時就立刻重送該區段,反應更快。

壅塞控制(congestion control)。 這是 TCP 最精妙之處。它要解決一個全域協調問題:無數連線共享有限頻寬,若大家都猛灌資料,網路會壅塞崩潰(congestion collapse)。TCP 維護一個壅塞視窗(cwnd, congestion window),限制尚未被確認的在途資料量,並透過經典的兩階段策略動態調整:

  • 慢啟動(slow start):cwnd 從一個很小的值開始,每收到一個 ACK 就指數成長(每個 RTT 大約加倍),快速探測可用頻寬。
  • 壅塞避免(congestion avoidance):當 cwnd 達到門檻(ssthresh)後改為線性成長(每 RTT 約加一),謹慎逼近極限。

一旦偵測到遺失(視為壅塞訊號),就大幅縮減視窗——這就是著名的 AIMD(Additive Increase, Multiplicative Decrease,加法增大、乘法減小) 原則。實際送出速率還受限於兩個視窗的較小者:

$$\text{有效視窗} = \min(\text{cwnd}, \text{rwnd})$$

其中 rwnd 是接收端宣告的接收視窗(receive window),用於流量控制(flow control)——確保不會把接收方緩衝區灌爆。流量控制(保護接收端)與壅塞控制(保護網路)是兩件不同的事,常被混淆,務必區分。

這些機制連結到更廣的議題。AIMD 之所以被選用,是因為理論上能讓多條競爭連線收斂到公平(fairness) 的頻寬分配,這可用「公平性圖」幾何地證明。而現代的壅塞控制已從以「遺失」為訊號(如 Reno、CUBIC)演進到以「延遲與頻寬量測」為訊號(如 Google 的 BBR),試圖在高頻寬高延遲的網路中取得更好的吞吐與更低的排隊延遲。再往上看,QUIC 協定把可靠傳輸與壅塞控制搬到 UDP 之上、整合 TLS 加密,並在使用者空間實作,正是為了擺脫 TCP 在作業系統核心中難以演進、以及隊頭阻塞(head-of-line blocking)的桎梏——這也說明,即便是看似穩固的基礎協定,網路的演化也從未停歇。

AI 共讀助教正在陪你讀:協定層與 TCP/IP:一封訊息如何穿過半個地球
嗨!我是這篇文章的共讀助教,只根據〈協定層與 TCP/IP:一封訊息如何穿過半個地球〉的內容回答。可以問我「解釋某段」「舉個例子」「出題考我」,或反白文中段落後點下方「解釋選取段落」。