絡協(xié)議:從分層模型到排查實戰(zhàn))
很多朋友在學網(wǎng)絡知識時最頭疼的不是某一個協(xié)議有多難而是協(xié)議數(shù)量太多不知道它們各自屬于哪一層也不知道報文格式長什么樣更不清楚出了問題該用什么命令去排查。本文整理了一張相對完整的“計算機網(wǎng)絡協(xié)議地圖”從上到下覆蓋數(shù)據(jù)鏈路層、網(wǎng)絡層、傳輸層和應用層把每層的主要協(xié)議、報文格式、核心功能以及對應的排查命令串成一條線。建議先收藏再花 20 分鐘通讀一遍之后無論是應付面試、做網(wǎng)絡實驗還是排查線上連通性問題都可以直接回到這篇文章里查。1. 為什么需要一張“協(xié)議地圖”1.1 計算機通信的復雜性兩臺設備要完成一次通信其實非常復雜。比如你用瀏覽器訪問一個網(wǎng)站背后至少包含把域名解析成 IP 地址。建立 TCP 連接。發(fā)送 HTTP 請求。經(jīng)過路由器逐跳轉(zhuǎn)發(fā)。最終把數(shù)據(jù)交給目標服務器的應用進程。如果所有邏輯都寫在一個協(xié)議里這個協(xié)議會非常臃腫而且很難擴展。所以計算機網(wǎng)絡采用了分層的設計思路每一層專注解決一類問題層與層之間通過標準接口協(xié)作。1.2 分層模型OSI 與 TCP/IP說到分層最經(jīng)典的是 OSI 七層模型但實際互聯(lián)網(wǎng)采用的是 TCP/IP 四層模型。兩者對應關(guān)系如下OSI 七層模型TCP/IP 四層模型典型協(xié)議示例應用層應用層HTTP、HTTPS、DNS、FTP、SMTP、SSH表示層應用層TLS/SSL加密與數(shù)據(jù)完整性會話層應用層RPC、會話管理傳輸層傳輸層TCP、UDP網(wǎng)絡層網(wǎng)絡層IP、ICMP、OSPF、BGP數(shù)據(jù)鏈路層數(shù)據(jù)鏈路層以太網(wǎng)、ARP、VLAN物理層數(shù)據(jù)鏈路層網(wǎng)線、光纖、Wi-Fi 物理信號學習時不必糾結(jié) OSI 的表示層和會話層TCP/IP 模型已經(jīng)把它們合并進應用層。重點要掌握的是從上往下數(shù)據(jù)一層層封裝從下往上數(shù)據(jù)一層層解封裝。1.3 數(shù)據(jù)封裝與解封裝一個 HTTP 請求從應用層出發(fā)會經(jīng)歷這樣的過程應用層生成 HTTP 報文。傳輸層添加 TCP 頭形成 TCP 報文段。網(wǎng)絡層添加 IP 頭形成 IP 數(shù)據(jù)報。數(shù)據(jù)鏈路層添加以太網(wǎng)幀頭和幀尾形成數(shù)據(jù)幀。物理層把數(shù)據(jù)幀轉(zhuǎn)換為比特流通過介質(zhì)傳輸。接收方則反向操作逐層去掉頭部最終把 HTTP 報文交給應用程序。這個過程稱為封裝與解封裝。理解它之后再看每一層的報文格式就不會感到孤立。2. 數(shù)據(jù)鏈路層數(shù)據(jù)幀的起點2.1 鏈路層的作用數(shù)據(jù)鏈路層解決的是“同一段物理鏈路內(nèi)設備之間如何傳輸數(shù)據(jù)單元”的問題。它把網(wǎng)絡層交下來的 IP 數(shù)據(jù)報封裝成幀在相鄰節(jié)點之間傳輸同時負責差錯檢測。鏈路層的核心包括幀的封裝與拆封。MAC 地址尋址。差錯檢測幀校驗。介質(zhì)訪問控制如以太網(wǎng)的 CSMA/CD 和無線網(wǎng)絡的 CSMA/CA。2.2 以太網(wǎng)幀格式以太網(wǎng)是使用最廣泛的鏈路層技術(shù)。標準的以太網(wǎng)幀格式如下字段長度字節(jié)說明目的 MAC 地址6接收方網(wǎng)卡的物理地址源 MAC 地址6發(fā)送方網(wǎng)卡的物理地址類型/長度20x0800 表示上層為 IPv40x86DD 表示 IPv6數(shù)據(jù)46-1500上層協(xié)議數(shù)據(jù)單元如 IP 數(shù)據(jù)報幀校驗序列4CRC 校驗結(jié)果用于差錯檢測MAC 地址是網(wǎng)卡出廠時燒錄的物理地址全球唯一從廠商角度說可保證唯一性。它只在同一鏈路內(nèi)有意義跨網(wǎng)絡轉(zhuǎn)發(fā)時幀頭會被不斷替換。2.3 ARP 協(xié)議與 MAC 地址解析ARPAddress Resolution Protocol地址解析協(xié)議用于根據(jù) IP 地址獲取同一鏈路內(nèi)的 MAC 地址。假設主機 A 知道目標主機 B 的 IP 是 192.168.1.10但不知道 B 的 MAC 地址A 會廣播一個 ARP 請求“誰是 192.168.1.10請告訴我你的 MAC 地址。”B 收到后回復單播 ARP 響應A 將結(jié)果寫入本機 ARP 緩存。在命令行執(zhí)行arp -a可以查看本機 ARP 緩存表arp -a輸出類似接口: 192.168.1.100 --- 0x9 Internet 地址 物理地址 類型 192.168.1.1 a4-2b-b0-xx-xx-xx 動態(tài) 192.168.1.10 68-9e-xx-xx-xx-xx 動態(tài)這里192.168.1.1通常是網(wǎng)關(guān) IP對應的是網(wǎng)關(guān)設備的 MAC 地址。注意即使目標服務器在公網(wǎng)報文要發(fā)送出去也必須先找到下一跳網(wǎng)關(guān)的 MAC 地址。2.4 鏈路層常用命令Windows 與 Linux 下查看鏈路層信息的命令略有差別但最常用的是# Windows 查看網(wǎng)卡信息包含 MAC 地址和 IP 地址 ipconfig /all # Linux 查看網(wǎng)卡信息 ip link show # 查看 ARP 緩存 arp -a # 清除 ARP 緩存需要管理員權(quán)限 arp -d *如果同一局域網(wǎng)內(nèi)兩臺主機 ping 不通第一步就應該檢查 IP 是否在同一網(wǎng)段第二步檢查 ARP 是否能解析到對端 MAC。3. 網(wǎng)絡層跨網(wǎng)絡的路徑規(guī)劃3.1 網(wǎng)絡層的作用網(wǎng)絡層解決的是“數(shù)據(jù)如何從源網(wǎng)絡到達目的網(wǎng)絡”的問題。它不關(guān)心具體哪臺主機而是通過 IP 地址標識主機所在的位置并通過路由協(xié)議選擇最佳路徑。網(wǎng)絡層的核心功能IP 地址編址與子網(wǎng)劃分。路由選擇。分組轉(zhuǎn)發(fā)。擁塞控制輔助性。3.2 IPv4 報文格式IPv4 是當前使用最廣泛的網(wǎng)絡層協(xié)議。它的報文格式需要重點掌握字段長度位說明版本4固定為 4表示 IPv4首部長度4IP 首部長度單位是 4 字節(jié)服務類型8區(qū)分優(yōu)先級、延遲、吞吐量等總長度16IP 數(shù)據(jù)報總長度單位是字節(jié)標識16分片時用于重組標志3是否允許分片、是否還有分片片偏移13分片在原報文中的偏移位置生存時間 TTL8每經(jīng)過一個路由器減 1為 0 時丟棄協(xié)議8上層協(xié)議類型6TCP17UDP1ICMP首部校驗和16只校驗 IP 首部源 IP 地址32發(fā)送方 IP目的 IP 地址32接收方 IPTTL 字段非常關(guān)鍵。它防止數(shù)據(jù)報在網(wǎng)絡中無限循環(huán)。執(zhí)行 ping 時TTL 還能幫我們初步判斷目標主機的操作系統(tǒng)類型例如 Windows 默認 TTL 通常是 128Linux 通常是 64。3.3 IPv6 與 ICMPIPv6 是為解決 IPv4 地址枯竭而設計的下一代協(xié)議地址長度為 128 位不再需要 NAT 也能實現(xiàn)全球唯一尋址。IPv6 報文頭比 IPv4 更簡潔固定為 40 字節(jié)并且取消了首部校驗和減輕了路由器處理壓力。ICMPInternet Control Message Protocol互聯(lián)網(wǎng)控制報文協(xié)議是網(wǎng)絡層的輔助協(xié)議用于傳遞差錯信息和控制信息。比如目標不可達。超時。重定向。Echo 請求與應答ping 命令的基礎。ping 命令實際發(fā)送的就是 ICMP Echo Request收到 ICMP Echo Reply 就說明目標可達。3.4 路由協(xié)議與常用命令路由協(xié)議按工作范圍分為內(nèi)部網(wǎng)關(guān)協(xié)議RIP、OSPF、IS-IS。外部網(wǎng)關(guān)協(xié)議BGP。它們本質(zhì)上是在路由器之間交換路由信息幫助路由器構(gòu)建路由表。實際排錯時我們更關(guān)注的是本機路由表和連通性命令# Windows 查看路由表 route print # Linux 查看路由表 ip route show # ping 測試連通性 ping -c 4 www.baidu.com # 跟蹤路由路徑確認經(jīng)過哪些中間節(jié)點 tracert www.baidu.com # Windows traceroute www.baidu.com # Linux如果ping通但業(yè)務訪問失敗問題可能不在網(wǎng)絡層而在傳輸層或應用層。4. 傳輸層端到端的可靠與高效4.1 傳輸層的作用傳輸層是網(wǎng)絡通信中承上啟下的關(guān)鍵一層。它負責端口尋址、分段重組、連接管理和可靠傳輸為上層應用提供端到端的通信服務。傳輸層最核心的兩個協(xié)議是 TCP 和 UDP。特性TCPUDP連接狀態(tài)面向連接無連接可靠性可靠傳輸盡最大努力交付傳輸效率較低較高數(shù)據(jù)邊界字節(jié)流無邊界數(shù)據(jù)報有邊界典型應用HTTP、FTP、SMTPDNS、視頻通話、游戲4.2 TCP 報文段格式TCP 報文段格式是面試和排錯中繞不開的重點字段長度位說明源端口16發(fā)送方端口號目的端口16接收方端口號序號32本報文段數(shù)據(jù)首字節(jié)的序號確認號32期望收到對方下一個字節(jié)的序號數(shù)據(jù)偏移4TCP 首部長度保留6保留字段標志位6URG、ACK、PSH、RST、SYN、FIN窗口16接收窗口大小用于流量控制校驗和16覆蓋首部和數(shù)據(jù)的校驗值緊急指針16配合 URG 使用六個標志位是最常見的考點SYN同步序號用于建立連接。ACK確認應答。FIN釋放連接。RST重置連接。PSH立即上交應用層。URG緊急數(shù)據(jù)。4.3 三次握手與四次揮手TCP 建立連接通過三次握手完成目的是讓雙方都確認自己和對方的收發(fā)能力正常。三次握手過程客戶端發(fā)送 SYN1Seqx。服務端回復 SYN1ACK1SeqyAckx1??蛻舳税l(fā)送 ACK1Seqx1Acky1。連接建立后雙方進入數(shù)據(jù)傳送階段。斷開連接時使用四次揮手因為 TCP 是全雙工通信每一方都需要單獨關(guān)閉發(fā)送通道。四次揮手過程主動方發(fā)送 FIN1Sequ。被動方回復 ACK1Acku1。被動方發(fā)送 FIN1Seqw。主動方回復 ACK1Ackw1。排錯時觀察 TCP 狀態(tài)很有用常用的狀態(tài)有 LISTEN、SYN_SENT、ESTABLISHED、TIME_WAIT、CLOSE_WAIT。比如大量 CLOSE_WAIT 連接堆積通常說明服務端代碼沒有正確關(guān)閉 Socket。4.4 UDP 數(shù)據(jù)報格式UDP 首部非常簡單只有 8 字節(jié)字段長度位說明源端口16可選無用時為 0目的端口16目標端口長度16UDP 數(shù)據(jù)報總長度校驗和16可選校驗優(yōu)點是開銷小、實時性好適合 DNS 查詢、RTP 音視頻流、在線游戲等場景。但它不保證數(shù)據(jù)一定到達也不保證到達順序所以上層應用需要自己做容錯處理。4.5 TLS 安全傳輸層TCP 之上的一層安全能力TLSTransport Layer Security常被稱為安全傳輸層協(xié)議但它不是替代 TCP 的傳輸層協(xié)議而是位于應用層與傳輸層之間用于在兩個通信應用程序之間提供保密性和數(shù)據(jù)完整性。HTTPS 實際上就是 HTTP over TLS。TLS 要解決三個問題機密性使用對稱加密加密業(yè)務數(shù)據(jù)。完整性使用 MAC 或 HMAC 校驗數(shù)據(jù)是否被篡改。身份認證使用數(shù)字證書確認服務器身份。一次簡化的 TLS 握手流程如下客戶端發(fā)送 ClientHello包含支持的 TLS 版本、加密套件列表和隨機數(shù)。服務端回復 ServerHello選定加密套件和協(xié)議版本并發(fā)送證書。客戶端驗證證書合法性生成預主密鑰用服務器公鑰加密后發(fā)送。雙方根據(jù)預主密鑰生成會話密鑰后續(xù)通信全部加密。現(xiàn)在的線上業(yè)務基本都要求全站 HTTPS。如果開發(fā)中用抓包工具查看 HTTP 明文流量沒問題但瀏覽器地址欄沒有小鎖就要檢查證書鏈是否完整、域名是否匹配、TLS 版本是否過舊。5. 應用層面向用戶的服務協(xié)議5.1 應用層的作用應用層離用戶最近定義了應用程序之間通信的數(shù)據(jù)格式和交互規(guī)則。我們平時說的“接口開發(fā)”“API 對接”本質(zhì)上是基于某種應用層協(xié)議的數(shù)據(jù)約定。應用層協(xié)議種類非常多下面挑幾個最常用的展開。5.2 DNS 域名解析DNSDomain Name System域名系統(tǒng)負責把人類易記的域名轉(zhuǎn)換成機器可讀的 IP 地址。常見的 DNS 記錄類型類型說明A域名指向 IPv4 地址AAAA域名指向 IPv6 地址CNAME域名別名指向另一個域名MX郵件交換記錄NS指定域名服務器TXT任意文本記錄常用于域名驗證常用的 DNS 排查命令# 查詢 A 記錄 nslookup www.baidu.com # 查詢 AAAA 記錄 nslookup -typeAAAA www.baidu.com # Linux 下也可以使用 dig dig www.baidu.com如果瀏覽器提示“無法解析服務器的 DNS 地址”可以先檢查本機 DNS 配置再嘗試更換公共 DNS。5.3 HTTP/HTTPS 協(xié)議HTTP 是 Web 世界的基礎協(xié)議基于請求-響應模型。一個 HTTP 請求包含請求行、請求頭和請求體響應則包含狀態(tài)行、響應頭和響應體。HTTP 狀態(tài)碼要理解語義狀態(tài)碼含義典型場景200請求成功頁面正常返回301永久重定向HTTP 跳轉(zhuǎn) HTTPS302臨時重定向登錄后跳轉(zhuǎn)404資源不存在路徑寫錯500服務器內(nèi)部錯誤后端代碼異常502網(wǎng)關(guān)錯誤Nginx 后無可用服務504網(wǎng)關(guān)超時接口響應超時常用的 HTTP 調(diào)試命令是 curl# 查看響應頭 curl -I https://www.baidu.com # 查看完整請求與響應 curl -v https://www.baidu.com # 指定請求方法并傳遞 JSON curl -X POST https://api.example.com/login \ -H Content-Type: application/json \ -d {username:admin,password:123456}5.4 文件與郵件協(xié)議FTP 用于文件傳輸使用 20 端口傳數(shù)據(jù)、21 端口傳控制命令。不過因為明文傳輸現(xiàn)在很多場景已經(jīng)改用 SFTP。郵件相關(guān)協(xié)議SMTP發(fā)送郵件25 端口。POP3收取郵件110 端口。IMAP同步郵件143 端口。如果做應用層開發(fā)郵件系統(tǒng)通常用 SMTP 發(fā)送、IMAP 同步很少再用 POP3。5.5 DHCP 與 SSHDHCPDynamic Host Configuration Protocol動態(tài)主機配置協(xié)議自動分配 IP 地址、子網(wǎng)掩碼、網(wǎng)關(guān)和 DNS。新設備接入局域網(wǎng)后先廣播 DHCP Discover再由 DHCP 服務器提供配置。SSH 是遠程登錄的事實標準默認端口 22使用非對稱加密完成認證和會話密鑰協(xié)商。日常開發(fā)中通過 SSH 登錄服務器執(zhí)行命令是最常見的操作。在嵌入式、車載通信、工業(yè)控制等“應用層開發(fā)”場景中協(xié)議的分層思想同樣適用。比如車輛 EMB 制動系統(tǒng)開發(fā)中CAN/LIN 等總線負責底層信號傳輸應用層則負責把信號解析成具體的制動請求和執(zhí)行反饋。無論底層介質(zhì)怎么變上層協(xié)議的設計仍然遵循分層、封裝、可靠性與實時性權(quán)衡的思路。6. 協(xié)議排查實戰(zhàn)從應用層下鉆到鏈路層6.1 一次完整的 HTTP 訪問流程假設你的電腦要訪問https://www.example.com數(shù)據(jù)包要經(jīng)歷的完整過程是應用層瀏覽器發(fā)起 HTTPS 請求完成 DNS 解析得到 IP。傳輸層與目標服務器建立 TCP 連接隨后完成 TLS 握手。網(wǎng)絡層封裝 IP 頭查詢路由表找到下一跳地址。數(shù)據(jù)鏈路層通過 ARP 獲取下一跳 MAC 地址封裝幀頭。物理層轉(zhuǎn)換為比特流發(fā)送出去。返回數(shù)據(jù)時服務器端同樣逐層封裝最終瀏覽器渲染頁面。6.2 常用網(wǎng)絡命令組合排查網(wǎng)絡問題建議按從下到上的順序執(zhí)行命令排查目標命令說明網(wǎng)卡是否正常ipconfig /all或ip link確認 IP、掩碼、網(wǎng)關(guān)局域網(wǎng)是否連通ping 網(wǎng)關(guān)IP確認鏈路層和網(wǎng)絡層正常公網(wǎng)是否連通ping 公網(wǎng)IP排除 DNS 干擾域名解析是否正常nslookup 域名檢查 DNS 解析結(jié)果端口是否可達telnet 目標IP 端口檢查 TCP 層連通性路由是否正常tracert 目標IP定位丟包和延遲節(jié)點本機連接狀態(tài)netstat -an查看端口監(jiān)聽和連接狀態(tài)在 Linux/macOS 下telnet可能未安裝可以使用nc -vz 目標IP 端口6.3 Wireshark 報文過濾基本用法Wireshark 是最好的協(xié)議學習工具沒有之一。抓包后可以通過過濾表達式快速定位# 只看某個 IP 的流量 ip.addr 192.168.1.10 # 只看 TCP 端口 80 的流量 tcp.port 80 # 看 HTTP 請求 http.request # 看 DNS 查詢 dns.flags.response 0 # 看 TCP 握手包 tcp.flags.syn 1 tcp.flags.ack 0抓包是理解報文格式最直觀的方式。比如在瀏覽器訪問一個網(wǎng)站同時用 Wireshark 過濾tcp.port 443就能親眼看到 TCP 三次握手的三個報文以及 TLS 握手的 ClientHello、ServerHello 等記錄。7. 常見問題與排查表格下面整理了一些實際排錯中高頻出現(xiàn)的問題問題現(xiàn)象常見原因解決思路局域網(wǎng)內(nèi) ping 不通IP 不在同一網(wǎng)段或 ARP 解析失敗檢查子網(wǎng)掩碼與網(wǎng)關(guān)執(zhí)行arp -a確認 MAC 是否正常公網(wǎng) IP 能 ping 通域名訪問失敗DNS 配置錯誤執(zhí)行nslookup檢查解析結(jié)果更換公共 DNSTCP 連接建立失敗目標端口未監(jiān)聽或被防火墻攔截使用netstat -an查看端口監(jiān)聽用telnet或nc測試端口連通性訪問網(wǎng)頁出現(xiàn) 502后端服務宕機或網(wǎng)關(guān)配置錯誤檢查 Nginx 上游配置確認后端進程存活大量 TIME_WAIT 連接短連接頻繁建立開啟連接復用或改用長連接HTTPS 證書報錯證書過期、域名不匹配、鏈不完整檢查證書有效期與 SAN 字段補齊中間證書視頻通話卡頓UDP 丟包或帶寬不足檢查網(wǎng)絡延遲和丟包率考慮 QoS 策略服務端大量 CLOSE_WAIT應用未正確關(guān)閉 Socket檢查代碼連接釋放邏輯限制連接空閑時間遇到問題不要急著看代碼。先確認網(wǎng)絡幾層分別是否正常再把范圍縮小到具體某一層很多疑難問題都能快速定位。8. 最佳實踐與工程建議8.1 設計上遵循分層但不死守分層協(xié)議分層是學習和排查的框架但實際工程中會有一些跨層優(yōu)化。例如 TLS 位于應用層和傳輸層之間CDN 會在網(wǎng)絡層或應用層做加速HTTP/3 直接把傳輸層換成了基于 UDP 的 QUIC。理解分層之后要懂得在合適的位置做優(yōu)化高頻小數(shù)據(jù)包優(yōu)先考慮 UDP減少握手開銷。電商交易、轉(zhuǎn)賬類接口必須用 TCP必要時引入分布式事務。音視頻傳輸考慮 UDP 加 FEC 前向糾錯或使用 WebRTC。接口調(diào)用鏈冗長考慮 HTTP/2 多路復用或升級 HTTP/3。8.2 排錯上先分層再定位建立一套自己的排錯順序先看應用層日志有沒有報錯接口返回什么狀態(tài)碼。再看傳輸層端口通不通TCP 狀態(tài)正不正常。然后看網(wǎng)絡層路由表對不對TTL 是不是消耗完。最后看鏈路層ARP 有沒有解析成功網(wǎng)卡是否異常。每次都按這個順序走能避免在錯誤的方向上浪費時間。8.3 安全上最小權(quán)限與加密網(wǎng)絡層到應用層每一層都存在安全風險鏈路層注意 ARP 欺騙重要網(wǎng)絡建議開啟端口安全和 DHCP Snooping。網(wǎng)絡層合理規(guī)劃 ACL限制不必要的入站和出站流量。傳輸層線上服務盡量使用 TLS 1.2 以上版本關(guān)閉弱加密套件。應用層對所有用戶輸入做校驗防止注入類攻擊。在生產(chǎn)環(huán)境修改防火墻規(guī)則、路由表、ACL 之前一定要先備份原配置評估影響范圍并在測試環(huán)境驗證。操作過程遵循最小權(quán)限原則避免在業(yè)務高峰期做高風險變更。8.4 抓包習慣保留現(xiàn)場定位復雜網(wǎng)絡問題時抓包是最有力的證據(jù)。建議抓包時同時抓客戶端和服務端兩側(cè)方便對比。保存抓包文件時帶上時間點和問題描述。用 Wireshark 的 Follow TCP Stream 功能查看完整會話。不要只抓業(yè)務端口DNS 查詢、ARP 請求也要關(guān)注。把每一次踩坑的報文和排查過程記錄下來慢慢就會形成屬于自己的“協(xié)議地圖”。下次再遇到類似的超時、丟包、連接異常一眼就能看出來問題出在哪一層。