正如標題所寫盏浙。這篇文章致力于網(wǎng)絡協(xié)議的初級掃盲、方便應對日常甚至面試中的尬聊荔茬、也是為了對剛補完的網(wǎng)絡協(xié)議做個歸納废膘。
目錄
- TCP/IP協(xié)議族的體系結構
- 四層協(xié)議模型
- 每層的作用
- TCP/IP協(xié)議整體的工作流程
- 網(wǎng)絡層
- 路由器是如何工作的?--路由協(xié)議
- 路由器
- 距離向量路由算法
- 鏈路狀態(tài)路由算法
- IP地址是個啥?--IP協(xié)議
- A慕蔚、B丐黄、C、D孔飒、E共五類網(wǎng)絡地址
- 子網(wǎng)掩碼
- 分片與重組
- NAT網(wǎng)絡地址轉換
- 未來的新型IP地址--IPv6
- MAC地址有什么作用灌闺?--ARP協(xié)議
- 我們總說ping一下。本質是個啥?--ICMP協(xié)議
- 如何動態(tài)分配IP地址坏瞄?--廣播與多播
- 路由器是如何工作的?--路由協(xié)議
- 傳輸層
- 套接字(socket)
- UDP協(xié)議
- TCP協(xié)議
- TCP協(xié)議與UDP協(xié)議的比較
- TCP應用于UDP應用
- 應用層
- 最后:網(wǎng)絡協(xié)議到底有沒有用?
TCP/IP協(xié)議族的體系結構
-
四層協(xié)議模型
雖然與OSI有所不同桂对、但也只是將某些層級合并了而已。
有人說是四層鸠匀、也有人說是五層(將網(wǎng)絡接口層分為數(shù)據(jù)鏈路層和物理層
)蕉斜。但是畢竟是個認為定義的東西、沒必要拼個你死我活缀棍、理解每一層的作用就好(也有人說ARP以及RARP該歸屬物理鏈路層宅此、一樣沒必要爭論
)。
-
每層的作用
嘗試性的總結以及類比一下睦柴、但是不確保100%吻合诽凌、因為現(xiàn)實畢竟和網(wǎng)絡上不同(你見過誰家快遞員專職住你公司里簽單子?)坦敌。
- 四層結構(橙色)全部處于主機內部侣诵、并且
源主機
和目標主機
甚至路由器
都含有它們。 - 應用層并不代指APP狱窘、而是供APP調用(
比如HTTP
)杜顺。 - 傳輸層負責這次傳輸?shù)木唧w規(guī)則(
重發(fā)、擁塞控制)
蘸炸。 - 網(wǎng)絡層只負責傳輸躬络、其余全部不管。
- 物理鏈路層實際上就是網(wǎng)卡(
比如以前手機的網(wǎng)卡不能連wifi
)搭儒。
-
TCP/IP協(xié)議整體的工作流程
原始數(shù)據(jù)包會經(jīng)過一層一層的封裝(為了讓下一層能夠識別必須添加特定的包頭
)穷当、向下傳遞提茁。而后在目的地一層一層將數(shù)據(jù)取出。
網(wǎng)絡層
是TCP/IP協(xié)議中最重要的一層
-
路由器是如何工作的?--路由協(xié)議
-
路由器
負責報文(數(shù)據(jù)包)的轉發(fā)以及路徑的選擇
包括但不限于家用路由器馁菜、這里更多的指運營商處的大型路由器茴扁。
路由表
路徑選擇
主要依靠路由表
(也就是通過我可以到達網(wǎng)絡的表格)實現(xiàn)。包括靜態(tài)路由表(網(wǎng)絡管理員負責建立汪疮、但基本沒人用
)以及動態(tài)路由表(通過路由協(xié)議建立
)峭火。
工作原理
- 如果目的地址存在于路由表中、那么直接轉發(fā)智嚷。
- 如果目的地址不存在于路由表中卖丸、那么則發(fā)給默認路由。
- 通過網(wǎng)絡號而不是整個IP地址進行路由判斷
-
路由協(xié)議
幫助路由器建立路由表
分為兩種算法實現(xiàn):
距離向量路由算法
要求路由器將自己的路由表發(fā)送到臨近的節(jié)點上
鏈路狀態(tài)路由算法
只發(fā)送路由表中描述自身鏈路狀態(tài)的部分到臨近的節(jié)點上
二者比較
鏈路狀態(tài)算法
相比距離向量算法
在大型網(wǎng)絡上更有優(yōu)勢盏道。
由于發(fā)送的數(shù)據(jù)更精簡稍浆、所以收斂速度更快、網(wǎng)絡開銷也更小摇天。
路由表到底有多大粹湃?
具體要看與自己需要選擇轉發(fā)的網(wǎng)絡有多大。
比如泉坐、對于家用路由器的路由表自然只要維護自己內部的主機就好为鳄、一旦發(fā)現(xiàn)數(shù)據(jù)包不數(shù)據(jù)自己內部就直接丟給默認端口(當然大型路由器也一樣)。
具體可以參閱《網(wǎng)絡協(xié)議補完計劃--路由協(xié)議》
————————
-
IP地址是個啥腕让?IP協(xié)議
一種無連接的傳輸協(xié)議孤钦。只負責數(shù)據(jù)包的傳輸、不對任何問題負責纯丸。
其實和UDP很像偏形、但是IP數(shù)據(jù)包的包頭中是不含端口號的、只針對主機(IP地址)之間進行傳輸觉鼻。
A俊扭、B、C坠陈、D萨惑、E共五類網(wǎng)絡地址
常用的網(wǎng)絡地址為ABC三類:
A類:0開頭、后24位作為主機號仇矾、其余作為網(wǎng)絡號庸蔼。
B類:10開頭、后16位作為主機號贮匕、其余作為網(wǎng)絡號姐仅。
C類:110開頭、后8位作為主機號、其余作為網(wǎng)絡號(最常用)
D類:用于UDP多播掏膏。
子網(wǎng)掩碼
對地址結構的擴展劳翰、用于確定網(wǎng)絡號與主機號的結構
比如有兩個C類地址、他們本屬不同的網(wǎng)絡馒疹。但如果合理使用子網(wǎng)技術磕道、就可以把他們的網(wǎng)絡號合并從而形成一個子網(wǎng)。
分片與重組
實際使用中經(jīng)常會遇到一個IP包傳輸不完(
比如途中某個物理網(wǎng)絡最大傳輸長度限制
)行冰、需要拆分的情況。
對于大于MTU(最大傳輸長度
)的數(shù)據(jù)包伶丐、會被拆分然后傳輸悼做、最后在目的地重組恢復。
分片動作通常由路由器完成哗魂、重組由目標主機完成(降低了中間路由器壓力)肛走。
需要注意的是一旦任何分片丟失、目的主機都會要求重傳所有分片
NAT網(wǎng)絡地址轉換
一種通過將內部不同
私網(wǎng)IP及端口
與公網(wǎng)端口綁定
录别、以達到內部所有計算機
通過一個公網(wǎng)IP
進行外界溝通的作用朽色。
我們現(xiàn)在基本都是使用了這個技術、如果你有兩臺主機就會發(fā)現(xiàn)他們的公網(wǎng)IP其實是相同的组题。
這個技術在很大程度上也緩解了IP地址不足的問題(雖然不能根治)葫男。
具體可以參閱《網(wǎng)絡協(xié)議補完計劃--IP協(xié)議》
————————
-
未來的新型IP地址--IPv6
- 擴展地址
有IPv4的32(46億個
)位擴展為128位(340萬億個
) - 簡化的包頭
- 流標記
相同流向的數(shù)據(jù)包不需要每次進行尋路
具體可以參閱《網(wǎng)絡協(xié)議補完計劃--IPv6》
————————
-
MAC地址有什么作用?--ARP協(xié)議
用IP地址映射所對應的MAC地址
在物理層上崔列、并不是通過IP地址來確定通訊目標(有可能是因為網(wǎng)絡興起初期協(xié)議很多梢褐、IP協(xié)議并不占主導
)、而是通過網(wǎng)卡的MAC地址赵讯。
IP地址指向最終的主機地址盈咳、而MAC地址指向下一跳的目標位置。
工作流程
①當電腦沒有網(wǎng)關(采用代理ARP)時:"跨網(wǎng)段訪問誰边翼,就問誰的MAC"
②當電腦有網(wǎng)關(采用正常ARP)時:"跨網(wǎng)段訪問誰鱼响,都問網(wǎng)關的MAC"
③無論哪種ARP,跨網(wǎng)段通信時组底,發(fā)送方請求得到的目標MAC地址都是網(wǎng)關MAC丈积。
與之對應的還有RARP協(xié)議(用于網(wǎng)絡中某些需要遠程啟動的無盤工作站獲取IP地址
)
具體可以參閱《網(wǎng)絡協(xié)議補完計劃--ARP協(xié)議和RARP協(xié)議》
————————
-
我們總說ping一下。本質是個啥?--ICMP協(xié)議
發(fā)現(xiàn)錯誤的路由器斤寇、向數(shù)據(jù)包的(通過IP數(shù)據(jù)包的信息獲取)源主機地址發(fā)送一個ICMP數(shù)據(jù)包桶癣、并且通過ICMP數(shù)據(jù)包報告出錯的原因。
ICMP協(xié)議是IP協(xié)議的補充娘锁、
ICMP與IP協(xié)議位于同一個層次
(IP層)牙寞,但ICMP報文是封裝在IP數(shù)據(jù)包的數(shù)據(jù)部分
進行傳輸?shù)摹?/p>-
總的來看可以分為如圖所示的三大 類:差錯報告、控制報文和請求應答報文:
大部分都是給源路由器看的(比如網(wǎng)絡不可達
/源抑制
等等)
我們日常用到的ping命令
:作用就是我們發(fā)送請求報文
、目標服務器返回一個應答報文
以此判斷目標主機是否存在
间雀。
具體可以參閱《網(wǎng)絡協(xié)議補完計劃--ICMP協(xié)議》
————————
如何動態(tài)分配IP地址悔详?--廣播與多播
動態(tài)主機配置協(xié)議(Dynamic Host Configuration Protocol,DHCP),在認定本地子網(wǎng)上有一個DHCP服務器主機或中繼主機的前提下,DHCP客戶主機向廣播地址(通常是255.255.255.255,因為客戶主機還不知道自己的IP地址惹挟、子網(wǎng)掩碼及本子網(wǎng)的受限廣播地址)發(fā)送自己的請求茄螃。
單播
點對點的通訊方式廣播(IPv4)
向所有的主機同時通訊多播(組播)
向某些主機同時通訊泛播(IPv6)
向任意一些主機中的某一個發(fā)起通訊。可以參照負載均衡來理解连锯、我想知道當前時間归苍、10個服務器有資格響應、但最終只有一個離我最近的服務器完成響應
运怖。
注意這里雖然在網(wǎng)絡層所提到的廣播多播拼弃、也就是通過特定的IP地址實現(xiàn)。例如:
主機位全部為1(xxx.xxx.xxx.255
)則為該網(wǎng)絡的廣播地址摇展。
但并不妨礙我們在UDP中使用:
比如我們可以監(jiān)聽一個端口吻氧、然后向本地廣播地址發(fā)送UDP數(shù)據(jù)包
進行本地群組聊天
或者通過單播地址
來點對點聊天
。
TCP不支持廣播和多播:具體等說到TCP時再說咏连。
具體可以參閱《網(wǎng)絡協(xié)議補完計劃--廣播與多播》
傳輸層
在運行在不同主機上的進程提供邏輯通訊的功能盯孙、使彼此感覺直接相連
-
套接字(socket)
總是成對出現(xiàn)、是應用層到傳輸層的門戶祟滴。
套接字本質上就是操作系統(tǒng)為傳輸層公開的API振惰、幫助我們組裝傳輸層數(shù)據(jù)包并交給IP層發(fā)送。
套接字(socket
)并不單指TCP(長連接
)垄懂、TCP/IP協(xié)議族中包括三種套接字:
- 流式套接字--TCP協(xié)議專屬
- 數(shù)據(jù)報套接字--UDP協(xié)議專屬
- 原始套接字--可以直接訪問IP層
我們可以舉個C語言socket編程的例子:
//創(chuàng)建一個TCP的scoket
SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//創(chuàng)建一個UDP的scoket
SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
——————
-
UDP協(xié)議--(用戶數(shù)據(jù)報協(xié)議(User Datagram Protocol))
不可靠的無連接的數(shù)據(jù)包傳輸服務
只負責發(fā)送报账、不保證安全性(確認到達)以及順序。這點其實和IP協(xié)議的本質一樣埠偿。
所以透罢、UDP可以在不建立連接的情況下隨意向主機的某個端口發(fā)送數(shù)據(jù)(但源主機并不知道是否發(fā)送成功、甚至目標主機都不知道是誰發(fā)來的數(shù)據(jù)
)冠蒋。
-
TCP協(xié)議--(傳輸控制協(xié)議Transmission Control Protocol))
面向鏈接的可靠的字節(jié)流傳輸服務
即TCP協(xié)議數(shù)據(jù)包會保證重發(fā)羽圃、有序還有擁塞控制。確保從發(fā)送方發(fā)出的數(shù)據(jù)抖剿、按照順序完整的交付給接收方朽寞。
所以、TCP鏈接需要經(jīng)歷三次握手(雙方確認相互可以收發(fā)數(shù)據(jù)
)斩郎、四次揮手(雙方先后申請斷開單向鏈接并被確認
)
此外TCP是全雙工的脑融、數(shù)據(jù)的發(fā)送、接收可以同時雙向進行缩宜。
————————
-
TCP協(xié)議與UDP協(xié)議的比較
借用《《知乎》》上的一個很有趣的例子:
亞當和夏娃分別生活在兩個山頭肘迎,山頭之間是萬丈深淵甥温,亞當采集野果需要分享給夏娃,如果他們之間有一條索道(物理連接)妓布,野果可以順著索道滑到夏娃那一邊姻蚓,那就沒有網(wǎng)絡協(xié)議什么事了。
事實上山頭之間沒有索道匣沼。但是亞當何等聰明狰挡,于是他想出了一個方法,假設亞當需要給夏娃10個野果释涛,否則她會餓死加叁。
============================
《《《《《《對于TCP》》》》》》
============================
連接建立
亞當對著夏娃大喊:愛妃,你聽得到嗎唇撬?
夏娃回應:孩他爹殉农,我聽得到!
亞當接著喊:那好局荚,我扔果子給你吃,你接到果子就喊一聲愈污,一共十個耀态。
運送貨物
于是亞當開始扔第一個,夏娃喊收到了一個暂雹。
亞當扔第二個首装,夏娃喊收到兩個。
超時重傳 ( timeout retransmit)
亞當扔第三個杭跪,可是夏娃遲遲沒有回音仙逻,亞當意識到可能果子落到懸崖了,于是重新扔涧尿,夏娃喊收到第三個系奉。
Advertised window size = 0
于是亞當連續(xù)扔了第四、五姑廉、六個缺亮,夏娃急了:孩他爹,慢點扔桥言,臣妾忙不過來了…
Advertised window size > 0
于是亞當坐下休息萌踱,愛妃又開始叫了:繼續(xù)扔吧。
亞當開始扔第七個号阿,夏娃喊收到七個并鸵。
…
關閉連接
終于亞當扔完了,亞當喊:愛妃扔涧,果子扔完了园担,寡人去忙別的了。
夏娃回復:好的,我也休息一下粉铐,再見疼约。
亞當:再見
以上的過程類似TCP連接的過程,TCP是一個虛擬連接
============================
《《《《《《對于UDP》》》》》》
============================
亞當和夏娃吵架了蝙泼,任憑亞當如何大聲喊程剥,夏娃躲在樹林后生悶氣,一聲不響汤踏,亞當害怕夏娃餓死织鲸,于是
開始自說自話朝著夏娃的山頭扔玉米棒子:
一個、兩個溪胶、三個…
一共扔了十個搂擦,但最終扔到對方山頭到底有幾個,亞當沒有底哗脖,也許有的玉米棒子落到懸崖了瀑踢,但是這個效率高啊,可以連續(xù)扔才避,以前扔10個果子需要一分鐘橱夭,現(xiàn)在只需要20秒。
亞當扔果子桑逝、扔玉米都有可能扔到懸崖下棘劣,但是扔果子為何可以確保對方收到十個?那是因為夏娃收到一個果子楞遏,然后喊收到了茬暇,如果沒有收到,亞當就重新扔寡喝,直到夏娃說收到了糙俗。而扔玉米棒子對方?jīng)]有確認,所以對于丟棄的情況無法知道预鬓,也無法重新扔臼节。
面向連接的傳輸服務
-
TCP以連接作為協(xié)議數(shù)據(jù)的最終目標
TCP協(xié)議的端口是可以復用
對于TCP協(xié)議,要成功建立一個新的鏈接珊皿,需要保證新鏈接四個要素組合體的唯一性:客戶端的IP网缝、客戶端的port、服務器端的IP蟋定、服務器端的port粉臊。也就是說,服務器端的同一個IP和port驶兜,可以和同一個客戶端的多個不同端口成功建立多個TCP鏈接(與多個不同的客戶端當然也可以)扼仲,只要保證【Server IP + Server Port + Client IP + Client Port】這個組合唯一不重復即可远寸。
-
UDP以端口作為協(xié)議數(shù)據(jù)的最終目標
UDP協(xié)議的端口不可復用
對于UDP協(xié)議、是以監(jiān)聽端口作為操作的屠凶。而且在協(xié)議中驰后、源端口和源IP地址都是可選項。哪怕不填(只制定了目的端口和目的地址)也可以成功發(fā)送矗愧。
-
TCP協(xié)議需要先建立連接灶芝、然后才能發(fā)送/接收數(shù)據(jù)
并且需要對很多細節(jié)進行協(xié)商(最大數(shù)據(jù)長度、窗口大小唉韭、初始序列號等) - UDP協(xié)議直接發(fā)送/接收數(shù)據(jù)
可靠的傳輸服務
-
TCP協(xié)議提供的是可靠的傳輸服務
以序列號保證有序夜涕、以重發(fā)機制保證成功發(fā)送。 -
UDP協(xié)議提供的是不可靠的傳輸服務
可能會丟失属愤、失序女器、重復等。
面向字節(jié)流的傳輸服務
-
TCP協(xié)議是以字節(jié)為單位流式傳輸數(shù)據(jù)
TCP的傳輸是無邊界的 -
UDP協(xié)議是以數(shù)據(jù)塊傳輸數(shù)據(jù)
UDP的傳輸是有邊界的
——————————
-
TCP應用于UDP應用
1. TCP
以可靠傳輸為基準:FTP住诸、Telnet驾胆、http、自建通道贱呐。
2. UDP
對時效性為基準:實時應用丧诺、多播式應用。
使用UDP時應該注意一下幾點:
1. 應用程序必須自己來保證可靠性
應用程序必須有自己的重發(fā)機制吼句、數(shù)據(jù)失序處理、流量控制等事格。
2. 應用程序必須自己來處理大塊數(shù)據(jù)
發(fā)送方對大塊數(shù)據(jù)進行分割惕艳、接收方還要進行重組
QQ就是采用《可靠的UDP》+TCP來實現(xiàn)。其中UDP主要負責通訊驹愚、TCP負責最低限度狀態(tài)的維持远搪。
影響TCP和UDP選擇的最大原因
很多游戲選擇UDP而非TCP、并不是因為來回的確認包會浪費資源或者拖慢網(wǎng)速(因為可靠的UDP也需要確認包
)逢捺、更不是三次握手谁鳍。
更重要的原因是TCP的阻塞窗口機制會《在發(fā)生阻塞時自動減少數(shù)據(jù)段的發(fā)送》、一旦網(wǎng)絡發(fā)生波動劫瞳、TCP的這個自宮機制會讓應用程序的延遲更高倘潜。而在網(wǎng)絡恢復后、TCP的慢啟動機制也會延緩恢復的時間志于。
關于TCP和UDP具體可以參閱《網(wǎng)絡協(xié)議補完計劃--TCP協(xié)議》涮因、《網(wǎng)絡協(xié)議補完計劃--UDP協(xié)議》
應用層
-
HTTP
HTTP連接最顯著的特點是客戶端發(fā)送的每次請求都需要服務器回送響應、在
請求結束后(HTTP1.0)恰當?shù)臅r候(keep-alive)伺绽、會主動釋放連接养泡。從建立連接到關閉連接的過程稱為“一次連接”嗜湃。
實際上HTTP就是對于TCP的二次封裝、使得我們只需要傳入很少的參數(shù)便能使用TCP鏈接以《請求--應答》的方式進行通訊澜掩。默認端口為80.
HTTP1.0:
- 無連接
每次通訊結束會自動釋放鏈接 - 無狀態(tài)
服務器無法記錄用戶以前的動作
HTTP1.1:
- 新頭部字段
主機名购披、身份認證、狀態(tài)管理和Cache緩存等 - Connection-Keep-Alive
保持長連接(默認開啟--但是服務器通常會偷偷的釋放掉連接以節(jié)省資源
) - 支持在一次連接中同時發(fā)出多個請求
但服務器端必須按照接收到客戶端請求的先后順序依次回送響應結果肩榕,以保證客戶端能夠區(qū)分出每次請求的響應內容刚陡。這也叫做《隊首阻塞》。 - 斷點續(xù)傳
HTTP2.0:
多路復用
基于二進制分幀層点把,HTTP 2.0可以在共享TCP連接的基礎上橘荠,同時發(fā)送請求和響應。HTTP消息被分解為獨立的幀郎逃,而不破壞消息本身的語義哥童,交錯發(fā)送出去,最后在另一端根據(jù)流ID和首部將它們重新組合起來
褒翰。頭部壓縮
更小的頭部體積贮懈、傳輸更快
HTTP狀態(tài)碼
1xx(臨時響應
)、2xx(請求成功
)优训、3xx(重定向
)朵你、4xx(客戶機錯誤
)、5xx(服務器錯誤
)揣非。
Cookie
服務器通過響應頭發(fā)送一個用于識別身份的cookie字符串
讓《客戶端保存》抡医、客戶端在之后的請求中將該cookie放在請求頭中發(fā)送
。
需要注意的是cookie是不能跨域的早敬、而且https和http共用同一個忌傻。
Session
與cookie客戶端保存不同、session是由《服務器生成并保存》每個連接者的身份信息(session)搞监。而這個身份信息與客戶端的cookie綁定水孩、所以也有人說session是基于cookie實現(xiàn)
的。
具體可以參閱《網(wǎng)絡協(xié)議補完計劃--HTTP協(xié)議》
——————————
HTTPS
負責《幫助服務器和客戶端在安全的環(huán)境下協(xié)商出一個秘鑰》以《進行加密傳輸》琐驴。
主要用到了三種技術:
- 使用
數(shù)字證書以及數(shù)字簽名
技術實現(xiàn)服務器公鑰認證 - 使用公鑰實現(xiàn)
在非對稱加密
狀態(tài)下協(xié)商通信秘鑰 - 使用通信秘鑰實現(xiàn)
對稱加密
狀態(tài)下的安全通信
具體可以參閱《網(wǎng)絡協(xié)議補完計劃--HTTPS》
最后:網(wǎng)絡協(xié)議到底有沒有用?
這個問題沒有定論俘种。因為對于絕大部分人而言、我們只需要了解HTTP绝淡、甚至連了解都不用只需要會調用API就夠了宙刘。
所以具體有沒有用、要看工作中有沒有遇到什么問題牢酵。
當項目足夠大荐类、或許就用得上了。
以美團移動網(wǎng)絡的架構作為例舉
這個架構圖基本上已經(jīng)涵蓋了目前所有的通訊方式茁帽、并加以合理利用
TCP子通道:
專用的TCP長連接通道玉罐。所有客戶端的HTTP請求默認都會被加工成二進制數(shù)據(jù)包放在專用的TCP通道發(fā)送給代理服務器屈嗤。
UDP子通道:
作為TCP的降級方案使用、如果TCP不同則嘗試使用UDP通道通訊吊输。
HTTP子通道:
當TCP與UDP均不可用饶号、則直接使用HTTP對業(yè)務服務器進行公網(wǎng)請求。
HTTP通道:
上傳和下載大數(shù)據(jù)包的請求如果放在長連上進行都有可能導致長連通道的擁堵季蚂,因此我們將CDN訪問茫船、文件上傳和頻繁的日志上報等放在公網(wǎng)利用HTTP短連進行請求,同時也減輕代理長連服務器的負擔扭屁。
WNS通道:
出于災備用TCP通道