標籤:
前言
作為一名程式員, 不可能不與網路打交道. 現在我們的手機, 電腦, 不誇張地說, 離開了網路就是一塊’廢鐵’, 它們的作用將大打折扣.. 本文的作用呢, 主要是針對不是非網路專業開發的人員準備的, 以’最短的時間, 瞭解計網最多的知識’為前提起筆.
目錄
- 概述
- 物理層
- 資料連結層
- 網路層
- 傳輸層
- 應用程式層
概述
先來瞭解下各種我們知道, 但是不太瞭解的專業名詞的意思
網際網路
網際網路
網際網路是當今世界上最大的網路, 是”網路的網路”. 即網際網路是所有網路互連起來的一個巨型網路.
網際網路的組成 :
- 邊緣部分 : 主機
- 核心部分 : 大量網路和串連這些網路的路由器(此路由器不是我們家用的路由器)
乙太網路
乙太網路是現在最常用的區域網路通訊協定, 乙太網路上傳輸的是MAC幀. 由於乙太網路同一時間只允許一台電腦發送資料, 所以必須有一套檢測機制, 那就是CSMA/CD協議 :
- 多點接入 : 多台電腦以多點接入的方式串連在一根匯流排上
- 載波監聽 : 不管是否正在發送, 每個站都必須不停地檢測通道
- 碰撞檢測 : 邊發送邊監聽
OSI
開放系統互相連線模型基本參考模型, 只要遵守這個OSI標準, 任何兩個系統都能進行通訊. OSI是七層協議體繫結構, 而TCP/IP是一個四層協議體繫結構, 於是我們採取折中的方法, 學習電腦網路原理的時候往往用的是五層協議的體繫結構 : 物理層, 資料連結層, 網路層, 傳輸層和應用程式層
協議體繫結構
物理層
電腦的世界裡只有0和1, 正如你現在所看這篇文章的文字, 儲存在電腦中也是一大串0和1的組合. 但是這些數字不能在真實的物理介質中傳輸的, 而需要把它轉換為光訊號或者電訊號, 所以這一層負責將這些位元流(0101)與光電訊號進行轉換.
如果沒有物理層, 那麼也就不存在互連網, 不存在資料的共用, 因為資料無法在網路中流動.
資料連結層
資料在這一層不再是以位元流的形式傳輸, 而是分割成一個一個的幀再進行傳輸.
MAC地址
又稱電腦的硬體地址, 被固化在適配器(網卡)ROM上的佔48位的地址. MAC地址可以用來唯一區別一台電腦, 因為它在全球是獨一無二的
封包交換
由於資料在這次曾要被分割成一個一個的幀, 由於不同的鏈路規定了不同的最大幀長, 即MTU(傳輸單元最大值), 凡是超出這個MTU的幀都必須被分塊. 例如一台貨車一次能運輸5噸的貨物, 而有條公路限載重2噸, 那麼你只好分3次運輸.
橋接器
橋接器工作在資料連結層, 根據MAC幀的目的地址對收到的幀進行轉寄和過濾.
乙太網路交換器
實際上就是一個多介面的橋接器, 乙太網路交換器的每個介面都直接與一個單個主機或另一個集線器相連, 可以很容易實現VLAN(虛擬區域網路)
乙太網路的MAC幀
MAC幀的格式為 :
MAC框架格式
- 目的地址 : 接收方48位的MAC地址
- 源地址 : 發送方48位的MAC地址
- 類型欄位 : 標誌上一層使用的是什麼協議, 0×0800為IP資料報
網路層
如果只有資料連結層沒有網路層, 資料就只能在同一條鏈路上傳輸, 不能跨鏈路傳輸. 有了網路層, 資料便能跨域不同的資料鏈路傳輸.
IP地址
IP地址又稱為軟體地址, 儲存在電腦的儲存空間上, IPv4地址為32位, IPv6地址為128位
IP地址和MAC地址
- 網路層以上使用IP地址, 資料連結層以下使用MAC地址
- IP地址是邏輯地址, MAC地址是物理地址
- IP分組中首部的源地址和目的地址在傳輸中不會改變, MAC幀中首部的源地址和目的地址每到一個路由器會改變一次
IP地址分類
IP地址 = {<網路號>, <主機號>}
A類地址 : 0.0.0.0 ~ 127.0.0.0
B類地址 : 128.0.0.0 ~ 191.255.0.0
C類地址 : 192.0.0.0 ~ 223.255.255.0
劃分子網之後的IP地址
IP地址 = {<網路號>, <子網號>, <主機號>}
例如某單位擁有一個B類IP地址, 145.13.0.0, 但凡目的地址為145.13.x.x的資料報都會被送到這個網路上的路由器R. 內部劃分子網後變成 : 145.13.3.0, 145.13.7.0, 145.13.21.0. 但是對外仍表現為一個網路, 即145.13.0.0. 這樣路由器R收到報文後, 再根據目的地址發到對應的子網上.
子網路遮罩
一般由一串1和一串0組成, 不管網路有沒有劃分子網, 將子網路遮罩和IP地址做按位與運算即可得出網路地址.
所有的網路都必須使用子網路遮罩, 同時在路由表中必須有子網路遮罩這一欄. 如果一個網路不劃分子網, 那麼該網路的子網路遮罩就是預設的子網路遮罩.
A類地址的預設子網路遮罩為255.0.0.0
B類地址的預設子網路遮罩為255.255.0.0
C類地址的預設子網路遮罩為255.255.255.0
儘管劃分子網增加了靈活性, 但是卻減少了能夠串連在網路上的主機總數.
構成超網的IP地址
IP地址 = {<網路首碼>, <主機號>}
使用網路首碼, 無分類域間路由選擇CIDR
例如, 128.14.35.7/20, 意思是前20位為網路首碼, 後12位為主機號. 另外, CIDR把網路首碼相同的連續的IP地址組成一個”CIDR地址塊”
位址遮罩 : CIDR使用32位的位址遮罩, 類似於子網路遮罩.
IP資料報
在網路層, 資料是以IP資料報(IP分組)的形式傳輸的
IP資料報的格式
首部前20位元組為固定長度, 是所有IP資料報必備的. 後4位元組是可選欄位, 其長度可變.
IP資料報首部固定的欄位分析 :
- 版本號碼 : IP協議的版本, IPv4或IPv6
- 首部長度 : 記錄了首部的長度, 最大為1111, 即15個32位字長, 即60位元組. 當首部長度不是4位元組的整數倍時, 需要使用最後的填充欄位加以填充.
- 服務類型 : 一般無用
- 總長度 : 指首部和資料之和的長度. 最大為216-1 = 65535位元組. 但是由於資料連結層規定每一幀的資料長度都有最大長度MTU, 乙太網路規定MTU為1500位元組, 所以超出範圍的資料報就必須進行分區處理
- 標識 : 每產生一個IP資料報, 計數器就+1, 並將此值賦值給識別欄位. 再以後需要分區的資料報中, 標識相同說明是同一個資料報
- 標誌 : 佔3位, 最低位記為MF(More Fragment). MF = 1說明還有分區; MF = 0說明這已經是最後一個分區. 中間一位記為DF(Don’t Fragment), 意思是不能分區. 只有當DF = 0時才允許分區.
- 段位移 : 又稱片位移, 相對於使用者資料欄位的起點, 該片從何處開始. 片位移以8個位元組為位移單位. 所以, 每個分區的長度一定是8位元組的整數倍.
- 存留時間 : TTL(Time To Live). 資料報能在網際網路中經過路由器的最大次數為255次, 每經過一個路由器則TTL – 1, 為0時丟棄該報文.
- 協議 : 記錄該報文所攜帶的資料是使用何種協議.
- 首部檢驗和 : 只檢驗資料報的首部, 不檢驗資料部分. 不為0則丟棄報文.
- 源地址和目的地址 : 不解釋
IP層轉寄分組的流程
每個路由器內部都維護一個路由表, 路由表包含以下內容(目的網路地址, 下一跳地址).
使用子網時分組轉寄時, 路由表必須包含以下三項內容: 目的網路地址, 子網路遮罩和下一跳地址.
特定主機路由 : 對特定的目的地址指明一個路由
預設路由 : 不知道分組該發給哪個路由器時就發給預設路由. 當一個網路只有很少的對外串連時使用預設路由非常合適.
路由器的分組轉寄演算法
- 從資料報中拿到目的IP地址D, 得出目的網路地址N
- 若N就是與此路由器直接相連的某個網路地址, 則直接交付(不需要再交給其他路由器轉寄, 直接找到該目的主機交付), 否則 -> (3)
- 若路由表中有目的地址為D的特定主機路由, 則把資料報傳給該路由器, 否則 -> (4)
- 若路由表中有到達網路N的路由, 則把資料報傳給該路由器, 否則 -> (5)
- 若路由表中有預設路由, 則交給該路由器, 否則 -> (6)
- 報告轉寄分組出錯
虛擬私人網路VPN
網際網路中的所有路由器對該目的地址是專用地址的資料報一律不轉寄, 下面有3種專用地址(虛擬IP地址)
- 10.0.0.0 ~ 10.255.255.255
- 172.16.0.0 ~ 172.31.255.255
- 192.168.0.0 ~ 192.168.255.255
假設現在公司A有一個部門在廣州和另一個在上海, 而他們在當地都有自己的專用網. 那麼怎麼將這兩個專用網串連起來呢?
- 租用電信的通訊線路為本機構專用, 但是太貴了
- 利用公用的網際網路當做通訊載體, 這就是虛擬私人網路VPN
網路位址轉譯NAT
多個專用網內部的主機公用一個NAT路由器的IP地址, 在主機發送和接收IP資料報時必須先通過NAT路由器進行網路位址轉譯.
NAT路由器的工作原理
不僅如此, NAT還能使用連接埠號碼, 搖身一變成為網路地址和連接埠轉換NAPT
ARP協議
ARP是解決同一個區域網路上的主機或路由器的IP地址和MAC地址的映射問題, 即 IP地址 -> ARP -> MAC地址
每一個主機都有一個ARP快取, 裡面有本區域網路上的各主機和路由器的IP地址到MAC地址的映射表. 以下是ARP的工作原理 :
ARP的工作原理.jpg
那如果是跨網路使用ARP呢?
- 在本網路上廣播
- 未找到該主機, 則到路由器
- 路由器幫忙轉寄(在另一網路上廣播)
- 找到了則完成ARP請求, 未找到則返回(2)
傳輸層
這一層是重中之重, 因為資料連結層, 網路層這兩層的資料轉送都是不可靠的, 盡最大能力交付的. 什麼意思的? 就是它們不負責提交給你的就是正確的資料. 然而這一層的TCP協議將要提供可靠傳輸
這一層主要重點是兩個協議 : UDP 和 TCP
使用者資料包通訊協定UDP
UDP主要特點 :
- 無串連
- 盡最大努力交付
- 面向報文 : 應用程式層交下來的報文直接加上UDP頭部就往IP層扔, 不合并也不拆分
- 沒有擁塞控制
- 支援一對一, 一對多, 多對一和多對多的互動通訊
- 首部開銷小, 只有8個位元組
UDP首部
UDP首部格式
- 源連接埠 : 源連接埠號碼. 在需要對方回信時選用, 不需要則全0
- 目的連接埠 : 目的連接埠號碼. 這在終點交付報文時必須要使用到
- 長度 : UDP資料報的長度, 最小值為8(僅有首部)
- 檢驗和 : 與IP資料報只檢驗首部不同的是, UDP需要把首部和資料部分一起檢驗
傳輸控制通訊協定TCP
TCP主要特點 :
- 連線導向的運輸層協議
- 每一條TCP串連只能有2個端點, TCP是點對點的
- 提供可靠交付
- 全雙工系統通訊
- 面向位元組流
TCP的工作流程
TCP位元組流
TCP的串連
TCP串連的端點叫通訊端(socket)
socket = (IP地址 : 連接埠號碼)
每一條TCP串連唯一地被通訊兩端的兩個端點(socket)所確定. 即 :
TCP串連 ::= {socket1, socket2} = {(IP1 : port1), (IP2 : port2)}
TCP報文段的首部
TCP報文段的首部
- 源連接埠和目的連接埠 : 同UDP連接埠作用
- 序號 : 本報文段的資料的第一個位元組的序號
- 確認號 : 期望收到對方下一個報文段的第一個資料位元組的序號
若確認號 = N, 則表明 : 到序號N-1為止的所有資料都已正常收到
- 資料位移 : TCP報文段的首部長度
- 保留 : 以後用, 目前為0
- 緊急URG : 若URG = 1時, 說明緊急指標欄位有效, 告訴系統這是緊急資料, 應儘快傳送. 例如突然要中斷傳送
- 確認ACK : ACK = 1時確認號才有效, ACK = 0時確認號無效. TCP規定, 串連建立後所有傳送的報文段都必須把ACK置1
- 推送PSH : 若PSH = 1, 則接收方收到報文段之後不再等到整個緩衝滿而是直接向上交付
- 複位RST : 當RST = 1, 說明TCP串連有嚴重錯誤, 必須釋放串連再重連
- 同步SYN : 在串連建立時用來同步序號. 當SYN = 1, ACK = 0時表明這是一個串連請求報文段, 對方若同意建立串連, 則在響應的報文段中置SYN = 1, ACK = 1
- 終止FIN : 當FIN = 1, 表明此報文段的發送方資料已發送完畢, 並要求釋放串連
- 視窗 : 告訴對方 : 從本報文段首部中的確認號算起, 接收方目前允許對方發送的資料量. 這是作為接收方讓發送方設定其發送視窗的依據
- 檢驗和 : 同UDP, 檢驗首部和資料部分
- 緊急指標 : 當URG = 1時有效, 指出緊急資料的末尾在報文段的位置
- 選項 : 最大可40位元組, 沒有則為0
最大報文段長度MSS(Maximum Segment Size) : 每一個TCP報文段中資料欄位的最大長度, 若不填寫則為預設的536位元組.
視窗
TCP中很重要的一個概念, 那就是視窗(發送視窗和接收視窗)
視窗
由於停止等待協議非常低效, 於是衍生出視窗這一概念. 為發送方維持的發送視窗, 位於發送視窗的5個分組都可以連續發送出去而不需要等待對方的確認. 每收到一個確認, 就把發送視窗前移一個分組的位置. 這大大提高了通道利用率!
接收方不必發送每個分組的確認報文, 而是採用累積確認的方式. 也就是說, 對按序到達的最後一個分組發送確認報文.
逾時重傳
如果發送方等待一段時間後, 還是沒收到 ACK 確認報文, 就會啟動逾時重傳. 這個等待的時間為重傳逾時時間(RTO, Retransmission TimeOut).
然而, RTO 的值不是固定的, 這個時間總是略大於串連往返時間(RTT,Round Trip Time). 假設報文發送過去需要5秒, 對方收到後發送確認報文回來也需要5秒, 那麼RTT就為10秒, 那這RTO就要比10秒要略大一些. 那麼超過RTO之後還沒有收到確認報文就認為報文丟失了, 就要重傳.
流量控制
利用滑動視窗和報文段的發送時機來進行流量控制.
擁塞控制
發送方維持一個擁塞視窗cwnd, 發送視窗 = 擁塞視窗.
慢開始 : cwnd = 1, 然後每經過一個傳輸輪次就翻倍
擁塞避免 : 讓cwnd緩慢增大, 每經過一個傳輸輪次就+1
慢開始門限ssthresh :
當cwnd < ssthresh, 使用慢開始演算法當cwnd > ssthresh, 使用擁塞避免演算法當cwnd = ssthresh, 隨意
擁塞控制
只要判斷網路出現擁塞, 把ssthresh設為當前發送擁塞視窗的一半(不能小於2), 並把cwnd設為1, 重新執行慢開始演算法.
除了慢開始和擁塞避免演算法外, 還有一組快重傳和快恢複演算法 :
快重傳 : 接收方及時發送確認, 而發送方只要一連收到三個重複確認, 馬上重傳
快恢複 : 當發送方一連收到三個重複確認時, ssthresh減半, cwnd設為ssthresh.
TCP三向交握
TCP三向交握建立串連和四次揮手中斷連線是面試愛問的知識點.
TCP三向交握
Q : 為什麼要三向交握, 兩次不可以嗎?
A : 試想一下, A第一次發送請求串連, 但是在網路某節點滯留了, A逾時重傳, 然後這一次一切正常, A跟B就愉快地進行資料轉送了. 等到串連釋放了以後, 那個迷失了的串連請求突然到了B那, 如果是兩次握手的話, B發送確認, 它們就算是建立起了串連了. 事實上A並不會理會這個確認, 因為我壓根沒有要傳資料啊. 但是B卻傻傻地以為有資料要來, 苦苦等待. 結果就是造成資源的浪費.
更加接地氣的解釋就是 : A打電話給B
第一次握手 : 你好, 我是A, 你能聽到我說話嗎第二次握手 : 聽到了, 我是B, 你能聽到我說話嗎第三向交握 : 聽到了, 我們可以開始聊天了三向交握其實就是為了檢測雙方的發送和接收能力是否正常, 你說呢?
TCP四次揮手
TCP四次揮手
Q : 為什麼要四次揮手, 而不是兩次, 三次?
A :
首先, 由於TCP的全雙工系統通訊, 雙方都能作為資料發送方. A想要關閉串連, 必須要等資料都發送完畢, 才發送FIN給B. (此時A處於半關閉狀態)
然後, B發送確認ACK, 並且B此時如果要發送資料, 就發送(例如做一些釋放前的處理)
再者, B發送完資料之後, 發送FIN給A. (此時B處於半關閉狀態)
然後, A發送ACK, 進入TIME-WAIT狀態
最後, 經過2MSL時間後沒有收到B傳來的報文, 則確定B收到了ACK了. (此時A, B才算是處於完全關閉狀態)
PS : 仔細分析以上步驟就知道為什麼不能少於四次揮手了.
Q : 為什麼要等待2MSL(Maximum Segment Lifetime)時間, 才從TIME_WAIT到CLOSED?
A : 在Client發送出最後的ACK回複,但該ACK可能丟失。Server如果沒有收到ACK,將不斷重複發送FIN片段。所以Client不能立即關閉,它必須確認Server接收到了該ACK。Client會在發送出ACK之後進入到TIME_WAIT狀態。Client會設定一個計時器,等待2MSL的時間。如果在該時間內再次收到FIN,那麼Client會重發ACK並再次等待2MSL。MSL指一個片段在網路中最大的存活時間,2MSL就是一個發送和一個回複所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那麼Client推斷ACK已經被成功接收,則結束TCP串連。
更加接地氣的解釋 :
第一次揮手 : A告訴B, 我沒資料發了, 準備關閉串連了, 你要發送資料嗎第二次揮手 : B發送最後的資料第三次揮手 : B告訴A, 我也要關閉串連了第四次揮手 : A告訴B你可以關閉了, 我這邊也關閉了
應用程式層
應用程式層協議最著名的就是HTTP, FTP了, 還有一個重要的DNS
網域名稱系統(DNS, Domain Name System)
DNS 能將網域名稱(例如, www.jianshu.com)解析成IP地址.
網域名稱伺服器分類
- 根網域名稱伺服器 : 最高層次的網域名稱伺服器
- 頂級網域名稱伺服器 : 如其名
- 許可權網域名稱伺服器 : 負責一個區的應伺服器
- 本地區名伺服器 : 主機發送DNS查詢請求就是發給它
DNS查詢
DNS查詢
- 主機向本地區名伺服器的查詢一般都是採用遞迴查詢
- 本地區名伺服器向根網域名稱伺服器的查詢通常是採用迭代查詢
遞迴查詢 : B問A廣州怎麼去, A不知道, A就問C, C不知道就問D...直到知道了再一層一層轉告直到A告訴B. 迭代查詢 : B問A廣州怎麼去, A不知道, A就告訴你可以去問C, 然後B就去問C, C不知道, C就告訴你可以去問D, 然後B就去問D...直到B知道為止
DNS查詢例子 : 網域名稱為x.tom.com的主機想知道y.jerry.com的IP地址
- 主機x.tom.com先向本地區名伺服器dns.tom.com進行遞迴查詢
- 本地區名伺服器採用迭代查詢. 它先問一個根網域名稱伺服器
- 根網域名稱伺服器告訴它, 你去問頂級網域名稱伺服器dns.com
- 本地區名伺服器問頂級網域名稱伺服器dns.com
- 頂級網域名稱伺服器告訴它, 你去問許可權網域名稱伺服器dns.jerry.com
- 本地區名伺服器問許可權網域名稱伺服器dns.jerry.com
- 許可權網域名稱伺服器dns.jerry.com告訴它所查詢的主機的IP地址
- 本地區名伺服器把查詢結果告訴主機x.tom.com
PS : 該查詢使用UDP, 並且為了提高DNS查詢效率, 每個網域名稱伺服器都使用快取.
URL
URL的格式 : <協議>://<主機>:<連接埠>/<路徑>, 連接埠和路徑有時可省略.
使用HTTP協議的URL : http://<主機>:<連接埠>/<路徑>, HTTP預設連接埠號碼是80
HTTP協議
HTTP是面向事務的, 即它傳輸的資料是一個整體, 要麼全部收到, 要麼全部收不到.
全球資訊網的工作過程
每一次HTTP請求就需要建立一次TCP串連和釋放TCP串連.
HTTP是無串連, 無狀態的. 每一次請求都是作為一次新請求.
HTTP/1.0 缺點 : 無串連, 每一次請求都要重建立立TCP串連, 所以每一次HTTP請求都要花費2倍RTT時間(一次TCP請求, 一次HTTP請求)
HTTP/1.1 : 使用持續串連, 即保持TCP串連一段時間.
HTTP/1.1持續工作的兩種工作方式 : 非流水線方式和流水線方式 非流水線方式 : 收到一個請求的響應再發下一個請求, 效率低, 浪費資源 流水線方式 : 能夠同時發送多個請求, 效率高
HTTP的GET和POST
GET 請求通常用於查詢、擷取資料,而 POST 請求則用於發送資料
GET 請求的參數在URL中, 因此絕不能用GET請求傳輸敏感性資料, 而POST 請求的參數在要求標頭中, 安全性略高於GET請求
ps : POST請求的資料也是以明文的形式存放在要求標頭中, 因此也不安全
Cookie
全球資訊網使用Cookie來跟蹤使用者, 表示HTTP伺服器和使用者之間傳遞的狀態資訊.
Cookie工作原理 :
1. 使用者瀏覽某網站, 該網站的伺服器為使用者產生一個唯一的識別碼, 並以此為索引在伺服器後端資料庫中產生一個項目2. 返回給使用者的HTTP響應報文中添加一條 "Set-cookie", 值為該識別碼, 如1233. 使用者的瀏覽器將該cookie儲存起來, 在用於繼續瀏覽該網站時發送的每一個HTTP請求都會有一行 Cookie: 123於是, 這個網站就知道Cookie為123的這個使用者做了什麼, 為這個使用者維護一個獨立的列表(如購物車)
當然, Cookie是把雙刃劍, 方便的同時也帶有危險性, 例如隱私泄露等, 使用者可以自行決定是否使用Cookie
Session
Cookie是儲存在用戶端上的, 而Session是儲存在伺服器中. 當伺服器收到使用者發出的Cookie時, 會根據Cookie中的SessionID來尋找對應的Session, 如沒有則會產生一個新的SessionID返回給使用者
總而言之, Cookie和Session就是同一樣東西存放地方不同而已.
HTTPS
HTTPS協議
HTTPS協議在HTTP協議的基礎上, 在HTTP和TCP中間加入了一層SSL/TLS加密層, 解決了HTTP不安全的問題: 冒充, 篡改, 竊聽三大風險.
對HTTPS是如何做到安全, 加密等有興趣的可以參考以下文章
SSL/TLS協議運行機制的概述
HTTPS科普掃盲帖
原文地址:你應該知道的電腦網路知識
你應該知道的電腦網路知識