把OSI參考模型看得明明白白 ── 解剖一個HTTP請求的七層結構

· · OSI參考模型, TCP/IP, 網路, Wireshark, Ethernet, TCP, HTTP, C#, .NET, Socket, 技術諮詢

OSI參考模型幾乎是每一本網路入門書一定會先介紹的內容,但常常聽到「七層的名稱背得出來,但老實說完全沒有畫面」的心聲。物理層、資料連結層、網路層……雖然靠死記硬背記下來了,卻常常搞不清楚自己寫的C#程式碼,或是眼前發生的通訊故障,究竟要怎麼跟那張七層的圖對應起來。

本部落格過去曾寫過像是誤以為TCP中Send的每個單位都能對應到一次ReceiveTCP重送造成工業相機通訊中斷的原因與排查等探討L4(傳輸層)行為的文章,卻一直沒有一篇文章整理過作為這些內容基礎的「層」這個概念本身。

本文的做法很簡單:實際做出一個承載HTTP GET請求的Ethernet訊框,從外層開始依序解剖。 七層並不只存在於概念圖裡,而是實際物理地嵌套在網路上流動的那171個位元組之中。只要親眼透過十六進位傾印和Wireshark看過一次,OSI參考模型就不再是需要死記硬背的東西了。

本文出現的程式碼,已整理成一組可建置、可執行的範例(訊框組裝與解剖函式庫、輸出可用Wireshark開啟的pcap檔、單元測試),公開在GitHub上。

osi-model-packet-anatomy - komurasoft-blog-samples (GitHub)

1. 先講結論

  • OSI參考模型不是「實作」,而是「語彙」。 現實中運作的網際網路是TCP/IP協定套件(實質上只有四層),OSI的七層協定本身在普及競爭中敗下陣來,並未被實際使用。留存下來的,是「用L2來切分問題」「這是L7的問題」這種作為共通語言的模型。12
  • 七層是以位元組序列的形式物理性地嵌套在一起的。 以承載HTTP GET的訊框來說,開頭14個位元組是Ethernet標頭(L2),接著20個位元組是IPv4標頭(L3),再接著20個位元組是TCP標頭(L4),剩下的則是HTTP文字內容(L7)。每一層的標頭都緊接在前一層之後開始,這一點可以直接透過本文的十六進位傾印和Wireshark確認。
  • 你直接寫的C#程式碼,其實只碰到L7的位元組序列。 傳給Socket.Send的只有應用程式資料,TCP、IP標頭是由作業系統的協定堆疊加上去的,Ethernet標頭與電氣訊號則是由NIC那一側負責。正因為如此,選擇使用HttpClientSslStream還是Socket,本質上就是在選擇「從哪一層開始把工作交給作業系統」。3
  • L5(工作階段層)、L6(表現層)在現實的協定堆疊中並不是以獨立層存在。 TLS和字元編碼承擔了它們部分的角色,但在TCP/IP模型裡,這些統統歸在應用層之下。「搞不懂L6到底是什麼」並不是你的問題,而是模型和現實出現落差的地方本來就在這裡。2
  • OSI模型在實務上真正派上用場的時刻,是故障排查與溝通的時候。 像「ping能通但HTTP卻失敗」這種情況,就可以判斷L3以下是活著的,該懷疑的是L4以上──這種用層的語彙來縮小範圍的方式,成為網路、基礎架構、應用程式開發人員之間都能通用的共同語言。

2. 為什麼OSI參考模型總是止步於死記硬背

許多解說都是從這種表格開始的。

名稱 說明
L7 應用層 為應用程式提供通訊服務
L6 表現層 轉換資料的表現形式
L5 工作階段層 管理通訊的開始與結束
L4 傳輸層 提供可靠的資料傳輸
L3 網路層 進行路徑選擇與定址
L2 資料連結層 進行鄰接節點間的資料傳輸
L1 實體層 將位元轉換為電氣訊號

這張表本身沒有錯,但每一行都是用抽象的詞彙寫成的,光是讀過去並不會浮現出具體的畫面。被告知「轉換資料的表現形式」,恐怕沒有人能馬上聯想到自己程式碼裡的哪一行對應到這句話。

還有一個該老實寫出來的歷史事實。OSI參考模型是ISO(國際標準化組織)與ITU-T所訂定的標準(ISO/IEC 7498-1、ITU-T X.200),原本是一個為七層各自配上對應的OSI協定群、規模宏大的整體構想。1 但在1990年代的普及競爭中,早已能實際運作的TCP/IP成為了事實上的標準,OSI協定本身幾乎沒有被真正使用過就落幕了。訂定網際網路基礎的RFC 1122,是用連結層、網際層(IP)、傳輸層、應用層這實質上的四層來說明整個世界的,並沒有對應L5、L6的獨立層。2

也就是說,我們現在學習OSI參考模型的意義,並不是「因為現實就是照這樣實作的」,而是為了取得「用層來思考」這個工具,以及故障排查時的共通語彙。只要抱持這個前提,就不必再糾結於「找不到L5和L6的實體」,一下子就會豁然開朗。

3. 正題:解剖一個HTTP請求

前言就到這裡,我們來看真正的東西。下面的十六進位傾印,是承載一個GET /index.html HTTP/1.1這個HTTP請求的Ethernet訊框(總共171個位元組)。這是開頭介紹的範例程式碼所組裝出來的結果,由於IPv4標頭檢查碼與TCP檢查碼都經過正確計算,所以拿去餵給Wireshark也會被顯示為一個正常的封包。

0000  02 00 00 00 00 01 02 00  00 00 00 02 08 00 45 00  ..............E.
0010  00 9d 12 34 40 00 40 06  3b 99 c0 00 02 0a c6 33  ...4@.@.;......3
0020  64 50 cb 84 00 50 00 00  03 e8 00 00 07 d0 50 18  dP...P........P.
0030  ff ff a3 05 00 00 47 45  54 20 2f 69 6e 64 65 78  ......GET /index
0040  2e 68 74 6d 6c 20 48 54  54 50 2f 31 2e 31 0d 0a  .html HTTP/1.1..
0050  48 6f 73 74 3a 20 65 78  61 6d 70 6c 65 2e 63 6f  Host: example.co
0060  6d 0d 0a 55 73 65 72 2d  41 67 65 6e 74 3a 20 4b  m..User-Agent: K
0070  6f 6d 75 72 61 53 6f 66  74 44 65 6d 6f 2f 31 2e  omuraSoftDemo/1.
0080  30 0d 0a 41 63 63 65 70  74 3a 20 74 65 78 74 2f  0..Accept: text/
0090  68 74 6d 6c 0d 0a 43 6f  6e 6e 65 63 74 69 6f 6e  html..Connection
00a0  3a 20 63 6c 6f 73 65 0d  0a 0d 0a                 : close....

看右側的ASCII顯示可以發現,從中途(偏移量0x36處)開始出現了GET /index.html HTTP/1.1這樣人類可以閱讀的文字。那麼,在它之前的54個位元組又是什麼呢?把這串資料餵給範例的解剖器,會得到以下的回報:

[ L2 Ethernet II | offset   0 |  14 bytes | dst=02:00:00:00:00:01 src=02:00:00:00:00:02 type=0x0800 (IPv4)
  [ L3 IPv4        | offset  14 |  20 bytes | 192.0.2.10 -> 198.51.100.80 TTL=64 proto=6 (TCP) checksum=OK
    [ L4 TCP         | offset  34 |  20 bytes | 52100 -> 80 [Psh, Ack] seq=1000 win=65535
      [ L7 HTTP        | offset  54 | 117 bytes | GET /index.html HTTP/1.1

這正是本文最希望大家仔細看的一張圖。重點有三個。

  1. 每一層都是從「前一層結束的地方」緊接著開始的。 Ethernet標頭是第0〜13個位元組,IPv4標頭是第14〜33個位元組,TCP標頭是第34〜53個位元組,HTTP則從第54個位元組開始。層並不是概念上的分類,而是可以直接指出是訊框開頭起算的位元組範圍
  2. 內側的層是外側層的「積載物(payload)」。 從Ethernet的角度來看,IPv4以後的內容都只是積載物,它並不關心裡面是不是TCP。從IP的角度來看,TCP以後是積載物;從TCP的角度來看,HTTP是積載物。每一層只讀取自己的標頭,對積載物本身不做任何處理,直接往上傳遞。正是這種「不去理會」的結構,構成了封裝(Encapsulation)
  3. L1(實體層)以及L5、L6並沒有出現在這張圖裡。 L1的工作是把這串位元組轉換成電氣訊號、光或無線電波,所以不會出現在傾印裡;而L5、L6如前一章所述,在明文的HTTP/1.1中並不存在獨立的實體。「七層裡,真正會出現在傾印中的只有四層」──這才是現實的樣貌。

再次強調,這並不是因為HTTP特別。無論是資料庫連線、gRPC,還是工業相機的GigE Vision,只要是Ethernet上的TCP/IP通訊,所有封包都是這種相同的嵌套結構。會改變的只是L7積載物的內容而已。

4. L2 資料連結層 ── 送到「隔壁」

按照解剖結果,我們從外側依序看下去。開頭14個位元組是Ethernet II標頭。

02 00 00 00 00 01   目的地MAC位址(6個位元組)
02 00 00 00 00 02   來源MAC位址(6個位元組)
08 00               EtherType = 0x0800(積載物為IPv4)

L2的工作是把資料送到同一個網路區段內的隔壁節點。目的地的指定使用MAC位址。MAC位址是分配給NIC的識別碼,原則上不會跨越路由器直接送到最終對象手上。從辦公室的PC送往Web伺服器的訊框,其目的地MAC並不是Web伺服器的MAC,而是預設閘道(路由器)的MAC

這裡許多人都會有的疑問是「既然有IP位址了,為什麼還需要MAC位址」。答案就在於層級的分工。IP位址是指向「最終目的地」的住址,MAC位址則是指向「下一段路要交給誰運送」的收件人名稱。用宅配來比喻的話,IP位址就是託運單上的送達地址,MAC位址則是「下一個轉運站」的名稱。託運單(L3)從頭到尾都不會變,但收件人名稱(L2)每一段路都會被替換掉。從IP位址查出鄰接節點MAC位址的機制就是ARP,可以用arp -a指令查看PC所記住的對應表。

從設備的角度來說,看著L2進行轉發的就是交換機(switching hub)。交換機只看目的地MAC位址來選擇連接埠,並不會去看積載物裡的IP位址。

5. L3 網路層 ── 送到世界的盡頭

接下來的20個位元組是IPv4標頭。摘出主要欄位如下。

45          版本=4、標頭長度=5個字(20位元組)
00 9d       總長度 157位元組(IP標頭+TCP+HTTP。不含Ethernet的14位元組)
40 06       TTL=64、協定=6(積載物為TCP)
3b 99       標頭檢查碼
c0 00 02 0a 來源IP   192.0.2.10
c6 33 64 50 目的地IP 198.51.100.80

L3的工作是不論要跨越多少台路由器,都要送到最終目的地的主機。相對於L2只運送一段路(一個hop),L3的目的地IP位址從通訊開始到結束都不會改變。路由器會查看收到的封包的目的地IP,判斷「接下來要交給哪一台路由器」,並把L2的標頭替換掉之後再送出去。

TTL(Time To Live)是能讓我們看見「跨越路由器」這個動作的欄位。每跨過一台路由器就會減1,一旦變成0,封包就會被丟棄,並向來源端回報錯誤。tracert(Windows的路徑追蹤指令)就是故意把TTL依序設為1、2、3……來送出封包,藉此把途中經過的路由器一台一台揪出來。也就是說,tracert輸出結果裡排列的每一行,正是「L3的hop」的實物。

6. L4 傳輸層 ── 送到哪一個處理程序

接下來的20個位元組是TCP標頭。

cb 84       來源連接埠 52100
00 50       目的地連接埠 80
00 00 03 e8 序號
00 00 07 d0 確認應答編號
50 18       標頭長度=5個字、旗標 [PSH, ACK]
ff ff       視窗大小
a3 05       檢查碼

到L3為止,封包已經送到了目的地的「主機(機器)」上。然而在那台機器裡,Web伺服器、資料庫,以及其他許多處理程序,可能同時都在進行通訊。L4的其中一項工作,就是利用連接埠號碼來判斷「該交給哪一個處理程序(的Socket)」。目的地連接埠80是「HTTP伺服器正在監聽的號碼」這一約定俗成的慣例,作業系統看到這個號碼,就會把資料放進對應處理程序的接收緩衝區。

TCP另一項重要的工作,是透過序號、確認應答、重送、流量控制,提供可靠的位元組串流4 這一部分的行為與應對方式,光是每個主題都足以寫成一篇文章,這裡就交給TCP訊息邊界的相關文章以及TCP重送的相關文章。在這裡,只要掌握「從L4往上,已經不再是網路的形狀,看起來更像是連接處理程序與處理程序之間的管線」這種感覺就好。

有一個能展現模型的理想與現實之間落差的有趣事實。TCP的檢查碼並不是只針對TCP段本身計算,而是被定義為要在前面加上一個排列了L3資訊(來源、目的地IP位址)的「偽標頭」之後再進行計算4 如果各層真的乾淨獨立,L4的計算裡就不該混入L3的位址。這正是一個很好的例子,說明OSI參考模型終究只是用來整理概念的地圖,而現實中的協定會依需要跨越層級。

7. L5、L6 ── 模型與現實出現落差的地方

到目前為止的解剖圖裡,並沒有出現L5(工作階段層)、L6(表現層)。這正是讓人覺得「搞不懂OSI」的最大原因,這裡就直接講清楚。

L5、L6在現實的TCP/IP協定堆疊中,並不是以獨立層的形式存在的。 在RFC 1122的網際網路模型裡,TCP之上的一切都是「應用層」。2 OSI模型原本設想的角色,在現實中被分散吸收到以下這些地方。

OSI的設想 現實中被吸收的場所範例
L5:對話(工作階段)的建立與管理 TLS的工作階段交握、HTTP的Cookie/權杖、應用程式本身的登入管理
L6:資料表現形式的轉換、加密 TLS的加密、字元編碼(UTF-8)、JSON等序列化格式

以HTTPS來說,TCP(L4)之上會夾一層TLS,HTTP則在其中流動。「TLS算是第幾層?」這個問題很容易被拿來當考題,但把它定死成一個答案並沒有實務上的意義。比起能不能馬上回答出「是L6」,更重要的是能說明它「在L4之上、L7之下,兼具L5、L6的角色」。

在.NET的程式碼裡,這種關係直接體現在類別的疊加方式上。用SslStreamTcpClient.GetStream()取得的L4串流包起來之後,Write寫入的明文就會先被加密成TLS紀錄,再交給TCP。5

using var client = new TcpClient("example.com", 443);
// 用TLS(相當於L5/L6)包住L4的位元組串流
using var ssl = new SslStream(client.GetStream());
await ssl.AuthenticateAsClientAsync("example.com");
// 這裡寫的是L7(HTTP)的明文。加密是SslStream的工作
await ssl.WriteAsync(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n..."));

用串流包住串流的這種結構,正是封裝的程式碼版本。在Wireshark裡觀察443連接埠的通訊時,會發現TCP積載物看起來只是一團不透明的Application Data,這也能從另一個方向反過來確認「L7被包進了相當於L6的包裹裡」。

8. 你寫的C#程式碼碰到的是哪一層

到這裡,我們把上述內容對應到Windows應用程式開發者的工具上。

實物範例 .NET API範例 由誰加上標頭
L7 應用層 HTTP、gRPC、自訂協定 HttpClientGrpc.Net.Client、自行組裝的電文 你的程式碼/函式庫
(相當於L5/L6) TLS、序列化、字元編碼 SslStreamJsonSerializerEncoding 函式庫
L4 傳輸層 TCP、UDP SocketTcpClientUdpClient(標頭由OS產生) 作業系統的協定堆疊
L3 網路層 IP、路由、ICMP PingNetworkInterface(僅供參照) 作業系統的協定堆疊
L2 資料連結層 Ethernet、Wi-Fi、ARP (一般應用程式無法直接碰到) NIC驅動程式/NIC
L1 實體層 電氣訊號、光、無線電波 ── NIC/纜線/空間

這張表可以讀出兩件事。

第一,API的選擇就是在選擇「從哪一層以下要交給作業系統負責」。 使用HttpClient可以連L7的組裝都交出去,而使用Socket的話,L7全部都要自己寫。反過來說,一般的Windows應用程式幾乎不會直接操作L3以下(raw socket需要系統管理員權限,也伴隨許多限制)。

第二,傳給Socket.Send的,其實「只有」L7的位元組序列。 範例的Part 2是一個透過loopback實際送出HTTP請求的示範,應用程式所準備的只有60個位元組的HTTP文字內容,第3章所看到的那54個位元組的標頭群,都是由作業系統和NIC加上去的。你應用程式裡的網路程式碼,其實只負責製作七層裡最內側的那份積載物──這就是OSI模型與你所寫程式碼之間精確的位置關係。

using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
await socket.ConnectAsync(IPAddress.Loopback, port);

byte[] request = Encoding.ASCII.GetBytes(
    $"GET / HTTP/1.1\r\nHost: localhost:{port}\r\nConnection: close\r\n\r\n");

// 傳進去的只有L7的位元組序列。TCP/IP/Ethernet的標頭
// 是在這個呼叫的另一側(作業系統和NIC)才被加上去的
int sent = await socket.SendAsync(request);

9. 動手做 ── 組出訊框,並用Wireshark開啟

為了把「讀懂了」變成「親眼看到了」,這裡介紹一下範例程式碼的執行方式。

範例的核心,是依照第3章那個順序,從L7往L2一層一層包起來組裝出訊框的SampleFrameBuilder。傳送時每一層會發生什麼事,直接對應到方法的排列順序。

public static byte[] BuildHttpGetFrame()
{
    // L7: 應用程式傳給Send的「只有」這串位元組
    byte[] http = Encoding.ASCII.GetBytes(HttpRequest);

    // L4: 由OS的協定堆疊在前面加上TCP標頭
    byte[] tcp = WrapInTcp(http);

    // L3: 再加上IPv4標頭
    byte[] ip = WrapInIpv4(tcp);

    // L2: 在交給NIC驅動程式之前加上Ethernet標頭
    return WrapInEthernet(ip);
}

執行示範程式時,除了會顯示十六進位傾印與嵌套結構的檢視畫面之外,還會把這個訊框輸出成一個pcap檔案

dotnet run --project samples/Demo

請試著用Wireshark開啟產生出來的sample-http-get.pcap6 中間的窗格會直向排列出Ethernet IIInternet Protocol Version 4Transmission Control ProtocolHypertext Transfer Protocol這四行,點擊其中任何一行,下方十六進位傾印中對應的位元組範圍就會被醒目標示出來。第3章的嵌套結構圖,等於是被業界標準工具重新呈現了一次。確認到這裡之後,接下來就可以試試真實的流量了。啟動Wireshark開始擷取,在篩選器輸入tcp.port == 443之類的條件,然後用瀏覽器打開任何一個網站,就能確認真實的通訊全部都是用這種嵌套結構組成的。

另外,在解剖器(PacketDissector)本身的實作裡,也埋了一些實務上值得學習的地方。例如在切出IPv4積載物時,不能直接切出接收緩衝區剩下的全部內容,而必須信任標頭裡的TotalLength欄位來決定切出的長度。這是因為Ethernet有最小訊框長度(60位元組)的限制,過短的封包尾端會被補上沒有意義的填充位元組。「用內側層的長度資訊,去除外側層造成的困擾(填充)」──這也是層級分工體現在實作上的一個範例,並已透過單元測試加以驗證。

10. 在實務中使用OSI模型 ── 用層的語彙來排查

前面提到「OSI是作為語彙留存下來的」。這裡舉兩個這種語彙真正派上用場的場景。

故障排查。 「連不上伺服器」這樣的報告,一旦翻譯成層的語彙,就能系統性地縮小範圍。固定的作法是從下層開始依序確認。

確認項目 使用的工具 能確定存活的層
連結燈、Wi-Fi連線指示 目視 L1〜L2
對同一區段的閘道執行ping ping 192.168.x.1 自己周邊的L3
對目標主機執行ping ping <目標> 整條路徑的L3
對目標連接埠建立TCP連線 Test-NetConnection <目標> -Port 443 L4(加上途中的防火牆)
送出HTTP請求 curl -v或應用程式本身 L7(加上TLS)

舉例來說,如果「ping能通,但Test-NetConnection卻失敗」,就代表L3以下是正常的,嫌疑會集中在堵住L4連接埠的某個因素上(服務停止、防火牆、連接埠設定錯誤)。如果「TCP能連上,但HTTP回傳400」,那就不是網路的問題,而是L7(請求內容本身)的問題。與其盲目地把纜線拔了又插,逐層確認到底活到哪一層──這才是OSI模型在實務上的用法。

溝通用的共通語言。 像「感覺是L2的問題,麻煩看一下交換機的連接埠」「那是L7的話題,該找應用程式團隊」這類對話,能在網路人員、基礎架構人員、應用程式開發人員之間準確地溝通。層的編號,是用來簡短表達責任分界點的業界共通座標。

11. 糾正常見的誤解

最後,統一糾正一些關於OSI參考模型常見的誤解。

  • 「網際網路是靠OSI的七層在運作的」 ── 並非如此。實際被實作出來的是TCP/IP(實質上四層),OSI是用於說明與溝通的參考模型。2
  • 「TCP/IP的四層和OSI的七層可以乾淨地對應起來」 ── L5〜L7的對應本質上是模糊的。「TCP/IP的應用層 = OSI的L5+L6+L7」這種表格經常可見,但如第7章所述,L5、L6的角色在現實中是分散在TLS或序列化格式裡的。
  • 「TLS是第6層(或第5層)的協定」 ── 硬要把它定死成一個層並沒有意義。正確的說法是:它在L4之上、L7之下,兼具相當於L5、L6的角色。
  • 「看連接埠號碼就能知道是什麼協定」 ── 連接埠80不代表就一定是HTTP。連接埠號碼只是一種慣例,實際流通的內容為何,要看積載物才會知道。範例的解剖器之所以不是靠連接埠號碼,而是靠內容開頭的字串來判斷是不是HTTP,正是這個原因。
  • 「交換機是L2、路由器是L3的設備」 ── 作為出發點是對的,但現實中還普遍存在L3交換機、依L4進行分流的負載平衡器、檢查L7的WAF等跨越多層的設備。用「這台設備會讀到哪一層」來理解,才是準確的方式。

12. 總結

  • OSI參考模型不是實作,而是用來以層思考的語彙。現實中運作的是TCP/IP(實質上四層)
  • 七層並不是概念圖,而是實際物理地嵌套在一個訊框的位元組序列裡(L2:第0〜13位元組,L3:第14〜33位元組,L4:第34〜53位元組,L7:第54位元組以後)
  • 每一層只讀取自己的標頭,對積載物(內側的層)不做任何處理──這就是封裝
  • L5、L6在現實的協定堆疊中並不是獨立存在的,TLS和編碼吸收了它們的角色
  • 你的C#程式碼寫的只有L7的位元組序列。TCP/IP標頭由作業系統負責,Ethernet由NIC負責
  • 實務上的用途,是從下層開始逐層確認存活狀態的故障排查,以及團隊之間的共通語言
  • 只要用範例程式碼組出訊框並用Wireshark開啟,本文的內容全部都能親眼確認

相關文章

相關諮詢領域

合同會社小村軟體承接進行TCP/IP通訊的Windows應用程式的設計與實作、在與工業設備通訊時「偶爾會斷線、變慢」等通訊異常的原因調查,以及使用封包擷取進行故障排查的支援。

參考連結

  1. ITU-T, X.200 : Information technology - Open Systems Interconnection - Basic Reference Model: The basic model. OSI基本參考模型的原始文件(與ISO/IEC 7498-1內容相同)。關於七層各自的定義。  2

  2. IETF, RFC 1122 - Requirements for Internet Hosts – Communication Layers. 訂定網際網路主機應實作的需求的RFC。關於用連結層、IP層、傳輸層、應用層這四層來整理協定套件。  2 3 4 5

  3. Microsoft Learn, Socket Class (System.Net.Sockets). .NET中的Socket API。關於應用程式只傳遞積載物,協定標頭的產生由作業系統的協定堆疊負責。 

  4. IETF, RFC 9293 - Transmission Control Protocol (TCP). TCP現行規格。關於透過序號、確認應答提供可靠性,以及檢查碼計算會用到包含IP位址的偽標頭。  2

  5. Microsoft Learn, SslStream Class (System.Net.Security). 關於包裝既有串流(通常是TCP的NetworkStream)以提供TLS加密與驗證的類別。 

  6. Wireshark Foundation, Wireshark User’s Guide. 關於擷取檔案的開啟方式、封包詳細窗格與位元組序列窗格的對應顯示,以及顯示篩選器的使用方式。 

共用相同標籤的最新文章。能以相近的主題延伸理解。

與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。

本文連結到以下服務頁面,歡迎從最接近的入口查看。

常見問題

整理諮詢這個主題時常見的問題。

OSI參考模型的七層,實際的網際網路真的有在用嗎?
沒有在用。現實中運作的網際網路是TCP/IP協定套件(實質上只有四層),OSI的七層協定本身在1990年代的普及競爭中敗下陣來,幾乎沒有真正被使用過就結束了。訂定網際網路基礎的RFC 1122,是以連結層、網際層(IP)、傳輸層、應用層這四層來說明整個世界的。留存下來的,是「用L2來切分問題」「這是L7的問題」這種用於故障排查與溝通的共通語彙模型。
工作階段層(L5)與表現層(L6)的實體到底在哪裡?
在現實的TCP/IP堆疊中,它們並不是以獨立層的形式存在。OSI模型當初設想的角色,在現實中是分散被其他機制吸收掉的:L5(對話的建立與管理)相當於TLS的交握、HTTP的Cookie/權杖;L6(資料表現形式的轉換、加密)相當於TLS的加密、字元編碼、JSON之類的序列化格式。硬要把「TLS算第幾層」定死並沒有實務上的意義,比較重要的是能說明它是「在L4之上、L7之下,兼具L5、L6角色」的存在。
既然已經有IP位址了,為什麼還需要MAC位址?
因為兩者在層級上的分工不同。IP位址(L3)是指向最終目的地的住址,從通訊開始到結束都不會改變。MAC位址(L2)則是指向「下一段路要交給誰運送」的收件人名稱,每跨越一台路由器就會被替換一次。從辦公室的PC送往Web伺服器的訊框,其目的地MAC並不是Web伺服器的MAC,而是預設閘道(路由器)的MAC。從IP位址查出鄰接節點MAC位址的機制就是ARP,可以用arp -a指令查看對應表。
OSI參考模型在實務上到底有什麼用?
用在故障排查和團隊間的溝通上。像「連不上伺服器」這樣的報告,可以透過從下層開始逐層確認存活狀態來系統性地縮小範圍:目視連結燈(L1〜L2)、對閘道執行ping(L3)、確認能否對對方連接埠建立TCP連線(L4)、送出HTTP請求(L7)。舉例來說,如果ping能通但TCP連線失敗,嫌疑就會集中在堵住L4連接埠的某個因素(服務停止、防火牆等)。此外,像「這是L2的問題,麻煩看一下交換機」這種說法,也能作為業界共通的座標,用簡短的語言傳達責任分界點。

作者檔案

本文作者的個人檔案頁面。

Go Komura

小村軟體有限公司 代表

以 Windows 軟體開發、技術諮詢與故障調查為中心,在難以重現的故障調查與既有資產仍在運作的專案上具有優勢。

回到部落格一覽