1.概述
OSI七層模型是萬(wàn)能的國(guó)際標(biāo)準(zhǔn)化組織(ISO)提出的一個(gè)試圖使各種計(jì)算機(jī)在世界范圍內(nèi)互連的理想標(biāo)準(zhǔn)
#從分層上來(lái)區(qū)分:
物理層:透明的傳輸比特流
數(shù)據(jù)鏈路層:建立邏輯鏈接、進(jìn)行硬件地址尋址淌实、差錯(cuò)效驗(yàn)等功能
網(wǎng)絡(luò)層:進(jìn)行邏輯地址尋址部宿,實(shí)現(xiàn)不同網(wǎng)絡(luò)之間的路徑選擇
傳輸層:定義傳輸數(shù)據(jù)的協(xié)議端口號(hào)叛复,以及流控和差錯(cuò)效驗(yàn)
會(huì)話層:建立兆旬、管理械哟、終止會(huì)話映凳。(在五層模型中已經(jīng)合并到了應(yīng)用層)對(duì)應(yīng)主機(jī)進(jìn)程录别,指本地主機(jī)與遠(yuǎn)程主機(jī)正在進(jìn)行的會(huì)話
表示層:數(shù)據(jù)的表示耕渴、安全德谅、壓縮。(在五層模型中已經(jīng)合并到了應(yīng)用層)
應(yīng)用層:網(wǎng)絡(luò)服務(wù)于最終用戶的一個(gè)接口
七層模型 | 五層模型 | 四層模型 |
---|---|---|
應(yīng)用層 | ||
表示層 | 應(yīng)用層 | 應(yīng)用層 |
會(huì)話層 | ||
傳輸層 | 傳輸層 | 傳輸層 |
網(wǎng)絡(luò)層 | 網(wǎng)絡(luò)層 | 網(wǎng)絡(luò)層 |
數(shù)據(jù)鏈路層 | 數(shù)據(jù)鏈路層 | 鏈接層/實(shí)體層 |
物理層 | 物理層 |
1.2 TCP/IP協(xié)議簇
#TCP
TCP是面向連接的一種傳輸控制協(xié)議萨螺。
TCP通過(guò)三次握手建立連接, 通過(guò)四次揮手?jǐn)嚅_(kāi)連接窄做。
TCP連接之后,客戶端和服務(wù)器可以互相發(fā)送和接收消息慰技,
在客戶端或者服務(wù)器沒(méi)有主動(dòng)斷開(kāi)之前椭盏,連接一直存在,故稱為長(zhǎng)連接吻商。
特點(diǎn):連接有耗時(shí)掏颊,傳輸數(shù)據(jù)無(wú)大小限制,準(zhǔn)確可靠,先發(fā)先至乌叶。
#UDP
UDP是無(wú)連接的用戶數(shù)據(jù)報(bào)協(xié)議盆偿。
所謂的無(wú)連接就是在傳輸數(shù)據(jù)之前不需要交換信息,
沒(méi)有握手建立連接的過(guò)程准浴,只需要直接將對(duì)應(yīng)的數(shù)據(jù)發(fā)送到指定的地址和端口就行事扭。
特點(diǎn): 不穩(wěn)定,速度快乐横,可廣播求橄,一般數(shù)據(jù)包限定64KB之內(nèi),先發(fā)未必先至葡公。
#HTTP
>> HTTP/1.0是基于TCP協(xié)議的應(yīng)用罐农,請(qǐng)求時(shí)需建立TCP連接,而且請(qǐng)求包中需要包含
請(qǐng)求方法催什,URI涵亏,協(xié)議版本等信息,請(qǐng)求結(jié)束后斷開(kāi)連接蒲凶,完成一次請(qǐng)求/響應(yīng)操作溯乒。故稱為短連接。
>> HTTP/1.1中的keep-alive所保持的長(zhǎng)連接則是為了優(yōu)化每次HTTP請(qǐng)求中TCP連接三次握手的麻煩和資源開(kāi)銷豹爹,
只建立一次TCP連接裆悄,多次的在這個(gè)通道上完成請(qǐng)求/響應(yīng)操作。
值得一提的是臂聋,服務(wù)器無(wú)法主動(dòng)給客戶端推送消息光稼。
#WebSocket
WebSocket也是一種協(xié)議,并且也是基于TCP協(xié)議的孩等。
具體流程是WebSocket通過(guò)HTTP先發(fā)送一個(gè)標(biāo)記了 Upgrade 的請(qǐng)求艾君,
服務(wù)端解析后開(kāi)始建立TCP連接,省去了HTTP長(zhǎng)連接每次請(qǐng)求都要上傳header的冗余肄方,
可以理解為WebSocket是HTTP的優(yōu)化冰垄,但WebSocket不僅僅在Web應(yīng)用程序上得到支持。
#HTTP权她、WebSocket與TCP的關(guān)系
HTTP通信過(guò)程屬于“你推一下虹茶,我走一下”的方式,客戶端不發(fā)請(qǐng)求則服務(wù)器永遠(yuǎn)無(wú)法發(fā)送數(shù)據(jù)給客戶端隅要,
WebSocket則在進(jìn)行第一次HTTP請(qǐng)求之后蝴罪,其他全部采用TCP通道進(jìn)行雙向通訊。
所以步清,HTTP和WebSocket雖都是基于TCP協(xié)議要门,但是兩者屬于完全不同的兩種通訊方式虏肾。
1.x TCP協(xié)議和UDP協(xié)議的區(qū)別
1.TCP協(xié)議面向連接,UDP協(xié)議面向非連接 (有無(wú)鏈接)
2.TCP協(xié)議傳輸速度慢欢搜,UDP協(xié)議傳輸速度快 (傳輸速度)
3.TCP協(xié)議保證數(shù)據(jù)順序封豪,UDP協(xié)議不保證 (數(shù)據(jù)的有序性,在IP層時(shí)炒瘟,數(shù)據(jù)包會(huì)變得無(wú)序)
4.TCP協(xié)議保證數(shù)據(jù)正確性吹埠,UDP協(xié)議可能丟包 (TCP保證數(shù)據(jù)的可靠性)
5.TCP協(xié)議對(duì)系統(tǒng)資源要求多,UDP協(xié)議要求少 (TCP和UDP占用的資源)
2.相關(guān)協(xié)議
2.1 WebSocket協(xié)議
2.1.1概述
WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議唧领。即允許服務(wù)端主動(dòng)向客戶端推送數(shù)據(jù)。
WebSocket通信協(xié)議于2011年被IETF定為標(biāo)準(zhǔn)RFC 6455雌续,并由RFC7936補(bǔ)充規(guī)范斩个。
WebSocket API也被W3C定為標(biāo)準(zhǔn), 是HTML5新增的協(xié)議。
WebSocket API中驯杜,瀏覽器和服務(wù)器只需要完成一次握手受啥,
兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸鸽心。
HTTP 有 1.1 和 1.0 之說(shuō)滚局,也就是所謂的 keep-alive ,把多個(gè) HTTP 請(qǐng)求合并為一個(gè)顽频,
但是 Websocket 其實(shí)是一個(gè)新協(xié)議藤肢,跟 HTTP 協(xié)議基本沒(méi)有關(guān)系,
只是為了兼容現(xiàn)有瀏覽器糯景,所以在握手階段使用了 HTTP 嘁圈。
2.1.1 為什么傳統(tǒng)的HTTP協(xié)議不能做到WebSocket實(shí)現(xiàn)的功能
這是因?yàn)镠TTP協(xié)議是一個(gè)請(qǐng)求-響應(yīng)協(xié)議,請(qǐng)求必須先由瀏覽器發(fā)給服務(wù)器蟀淮,
服務(wù)器才能響應(yīng)這個(gè)請(qǐng)求最住,再把數(shù)據(jù)發(fā)送給瀏覽器。
換句話說(shuō)怠惶,瀏覽器不主動(dòng)請(qǐng)求涨缚,服務(wù)器是沒(méi)法主動(dòng)發(fā)數(shù)據(jù)給瀏覽器的。
這樣一來(lái)策治,要在瀏覽器中搞一個(gè)實(shí)時(shí)聊天脓魏,或者在線多人游戲的話就只能借助Flash這些插件。
也有人說(shuō)通惫,HTTP協(xié)議其實(shí)也能實(shí)現(xiàn)啊轧拄,比如用輪詢或者Comet。
#ajax輪詢
ajax輪詢的原理非常簡(jiǎn)單讽膏,讓瀏覽器隔個(gè)幾秒就發(fā)送一次請(qǐng)求檩电,詢問(wèn)服務(wù)器是否有新信息。
這個(gè)機(jī)制的缺點(diǎn)一是實(shí)時(shí)性不夠,二是頻繁的請(qǐng)求會(huì)給服務(wù)器帶來(lái)極大的壓力俐末。
#Comet
本質(zhì)上也是輪詢料按,但是在沒(méi)有消息的情況下,服務(wù)器先拖一段時(shí)間卓箫,等到有消息了再回復(fù)载矿。
這個(gè)機(jī)制暫時(shí)地解決了實(shí)時(shí)性問(wèn)題,但是它帶來(lái)了新的問(wèn)題:
以多線程模式運(yùn)行的服務(wù)器會(huì)讓大部分線程大部分時(shí)間都處于掛起狀態(tài)烹卒,極大地浪費(fèi)服務(wù)器資源吉捶。
另外薯鳍,一個(gè)HTTP連接在長(zhǎng)時(shí)間沒(méi)有數(shù)據(jù)傳輸?shù)那闆r下,鏈路上的任何一個(gè)網(wǎng)關(guān)都可能關(guān)閉這個(gè)連接,
而網(wǎng)關(guān)是我們不可控的仅胞,這就要求Comet連接必須定期發(fā)一些ping數(shù)據(jù)表示連接“正常工作”惦蚊。
以上兩種機(jī)制都治標(biāo)不治本呼猪,所以卤档,HTML5推出了WebSocket標(biāo)準(zhǔn),
讓瀏覽器和服務(wù)器之間可以建立無(wú)限制的全雙工通信谣辞,任何一方都可以主動(dòng)發(fā)消息給對(duì)方迫摔。
WebSocket對(duì)客戶端和服務(wù)端的要求
#瀏覽器
要支持WebSocket通信,瀏覽器得支持這個(gè)協(xié)議泥从,這樣才能發(fā)出ws://xxx的請(qǐng)求句占。
目前,支持WebSocket的主流瀏覽器如下:
>> Chrome
>> Firefox
>> IE >= 10
>> Sarafi >= 6
>> Android >= 4.4
>> iOS >= 8
#服務(wù)器
由于WebSocket是一個(gè)協(xié)議躯嫉,服務(wù)器具體怎么實(shí)現(xiàn)辖众,取決于所用編程語(yǔ)言和框架本身。
1) Node.js
本身支持的協(xié)議包括TCP協(xié)議和HTTP協(xié)議和敬,要支持WebSocket協(xié)議凹炸,
需要對(duì)Node.js提供的HTTPServer做額外的開(kāi)發(fā)。
2) java
3) python
2.1.2 WebSocket的握手通信過(guò)程
>> WebSocket并不是全新的協(xié)議昼弟,而是利用了HTTP協(xié)議來(lái)建立連接啤它。
>> WebSocket 是獨(dú)立的、創(chuàng)建在 TCP 上的協(xié)議舱痘。
>> Websocket 通過(guò)HTTP/1.1 協(xié)議的101狀態(tài)碼進(jìn)行握手变骡。
>> 為了創(chuàng)建Websocket連接,需要通過(guò)瀏覽器發(fā)出請(qǐng)求芭逝,之后服務(wù)器進(jìn)行回應(yīng)塌碌,這個(gè)過(guò)程通常稱為握手(handshaking)。
1) 首先旬盯,WebSocket連接必須由瀏覽器發(fā)起台妆,因?yàn)檎?qǐng)求協(xié)議是一個(gè)標(biāo)準(zhǔn)的HTTP請(qǐng)求翎猛,格式如下:
"GET ws://localhost:3000/ws/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13"
#該請(qǐng)求和普通的HTTP請(qǐng)求有幾點(diǎn)不同:
>> GET請(qǐng)求的地址不是類似/path/,而是以ws://開(kāi)頭的地址接剩;
>> 請(qǐng)求頭Upgrade: websocket和Connection: Upgrade表示這個(gè)連接將要被轉(zhuǎn)換為WebSocket連接切厘;
>> Sec-WebSocket-Key: 是瀏覽器經(jīng)過(guò)Base64加密后的密鑰,用來(lái)和response里面的Sec-WebSocket-Accept進(jìn)行比對(duì)驗(yàn)證
>> Sec-WebSocket-Extensions是對(duì)WebSocket的協(xié)議擴(kuò)展
>> Sec-WebSocket-Version指定了WebSocket的協(xié)議版本懊缺。
>> 請(qǐng)求返回101狀態(tài)碼, 如果不是101狀態(tài)碼疫稿,表示握手升級(jí)的過(guò)程失敗了
101是Switching Protocols,表示服務(wù)器已經(jīng)理解了客戶端的請(qǐng)求,
并將通過(guò)Upgrade 消息頭通知客戶端采用不同的協(xié)議來(lái)完成這個(gè)請(qǐng)求鹃两。
在發(fā)送這個(gè)響應(yīng)后的空檔遗座,將http升級(jí)到webSocket。
2) 隨后俊扳,服務(wù)器如果接受該請(qǐng)求途蒋,就會(huì)返回如下響應(yīng):
"HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string"
該響應(yīng)代碼101表示本次連接的HTTP協(xié)議即將被更改,
更改后的協(xié)議就是Upgrade: websocket指定的WebSocket協(xié)議拣度。
版本號(hào)和子協(xié)議規(guī)定了雙方能理解的數(shù)據(jù)格式碎绎,以及是否支持壓縮等等螃壤。
如果僅使用WebSocket的API抗果,就不需要關(guān)心這些。
現(xiàn)在奸晴,一個(gè)WebSocket連接就建立成功冤馏,瀏覽器和服務(wù)器就可以隨時(shí)主動(dòng)發(fā)送消息給對(duì)方。
消息有兩種寄啼,一種是文本逮光,一種是二進(jìn)制數(shù)據(jù)。
通常墩划,我們可以發(fā)送JSON格式的文本涕刚,這樣,在瀏覽器處理起來(lái)就十分容易乙帮。
#為什么WebSocket連接可以實(shí)現(xiàn)全雙工通信而HTTP連接不行呢杜漠?
實(shí)際上HTTP協(xié)議是建立在TCP協(xié)議之上的,TCP協(xié)議本身就實(shí)現(xiàn)了全雙工通信察净,
但是HTTP協(xié)議的請(qǐng)求-應(yīng)答機(jī)制限制了全雙工通信驾茴。
WebSocket連接建立以后,其實(shí)只是簡(jiǎn)單規(guī)定了一下:
接下來(lái)氢卡,咱們通信就不使用HTTP協(xié)議了锈至,直接互相發(fā)數(shù)據(jù)吧。
#安全的WebSocket連接機(jī)制和HTTPS類似:
首先译秦,瀏覽器用wss://xxx創(chuàng)建WebSocket連接時(shí)峡捡,會(huì)先通過(guò)HTTPS創(chuàng)建安全的連接击碗,
然后,該HTTPS連接升級(jí)為WebSocket連接棋返,底層通信走的仍然是安全的SSL/TLS協(xié)議延都。
2.1.3 WebSocket 的其他特點(diǎn)
>> 建立在 TCP 協(xié)議之上,服務(wù)器端的實(shí)現(xiàn)比較容易睛竣。
>> 與 HTTP 協(xié)議有著良好的兼容性晰房。
默認(rèn)端口也是80和443,并且握手階段采用 HTTP 協(xié)議射沟,
因此握手時(shí)不容易屏蔽殊者,能通過(guò)各種 HTTP 代理服務(wù)器。
>> 數(shù)據(jù)格式比較輕量验夯,性能開(kāi)銷小猖吴,通信高效。
>> 可以發(fā)送文本挥转,也可以發(fā)送二進(jìn)制數(shù)據(jù)海蔽。
>> 沒(méi)有同源限制,客戶端可以與任意服務(wù)器通信绑谣。
>> 協(xié)議標(biāo)識(shí)符是ws(如果加密党窜,則為wss),服務(wù)器網(wǎng)址就是 URL借宵。
2.1.4 WebSocket適用場(chǎng)景
追求數(shù)據(jù)的實(shí)時(shí)更新的應(yīng)用, 例如:
>> 股票交易數(shù)據(jù)
>> 數(shù)據(jù)貨幣交易數(shù)據(jù)等
>> 消息傳遞應(yīng)用程序
>> 在線多人游戲
>> 聊天室
>> 現(xiàn)場(chǎng)體育更新
>> 社交媒體
參考資料
http://www.websocket.org/index.html
https://segmentfault.com/a/1190000012709475
https://www.liaoxuefeng.com/wiki/1022910821149312/1103303693824096
https://www.cnblogs.com/nnngu/p/9347635.html
https://www.cnblogs.com/bianzy/p/5822426.html
https://www.cnblogs.com/jingmoxukong/p/7755643.html (nginx代理WebSocket)
https://segmentfault.com/a/1190000012948613
http://www.reibang.com/p/42260a2575f8
2.2 RPC
http://www.reibang.com/p/45cbc2252c11 (參考資源)
2.3 IP協(xié)議
http://www.reibang.com/p/9e63767c04e1
2.3.1 IP理論部分
IP數(shù)據(jù)包由IP頭部和數(shù)據(jù)負(fù)載兩部分組成幌衣。
IP數(shù)據(jù)包長(zhǎng)度不固定,其中頭部長(zhǎng)度不固定壤玫,負(fù)載長(zhǎng)度也不固定豁护。
1.版本:占4位,表示IP協(xié)議的版本欲间。如果是IPv4楚里,則取值為0100,如果是IPv6,則取值為0110
2.IP包頭長(zhǎng)度:
占4位猎贴,從0000-1111班缎,也就是最小為0,最大為15嘱能。
實(shí)際上吝梅,IP包頭的長(zhǎng)度至少為20字節(jié),最大為60字節(jié)惹骂。
IP包頭長(zhǎng)度的值 * 4就是ip包頭所占的字節(jié)數(shù)苏携。
舉例來(lái)說(shuō),IP包頭長(zhǎng)度的值是0110对粪,值為6右冻,那么IP包頭的長(zhǎng)度就是6 * 4 = 24装蓬。
固定區(qū)域20字節(jié),可選區(qū)域4字節(jié)纱扭。
3.服務(wù)類型:占8位牍帚,包含優(yōu)先級(jí)、標(biāo)志位等乳蛾,實(shí)際中很少使用暗赶,不做介紹。
4.IP包總長(zhǎng)度:占16位肃叶,表示該IP包的總長(zhǎng)度蹂随。即IP包頭長(zhǎng)度+IP包數(shù)據(jù)長(zhǎng)度。
5.標(biāo)識(shí):占16位因惭,在數(shù)據(jù)包分段重組時(shí)岳锁,標(biāo)識(shí)表示包的序列號(hào)。
當(dāng)數(shù)據(jù)包比較大時(shí)蹦魔,會(huì)分成多個(gè)IP包發(fā)送,每個(gè)IP包到達(dá)目的地的時(shí)間是不確定的乒躺,此時(shí)就需要根據(jù)標(biāo)識(shí)進(jìn)行重組聪蘸。
標(biāo)識(shí)符與下面的標(biāo)志表制、偏移量結(jié)合使用控乾。
6.標(biāo)志:占3位蜕衡。從左至右依次是MF、DF久脯、未使用字段镰吆。
MF = 1,表示后面還有分段數(shù)據(jù)包万皿,MF = 0表示后面沒(méi)有分段數(shù)據(jù)包摧找,也就是最后一個(gè)核行。
DF = 1,表示該數(shù)據(jù)包不能被分段蹬耘,DF = 0表示數(shù)據(jù)包可以被分段芝雪。
7.偏移量:占13位。表示該數(shù)據(jù)段在上層初始數(shù)據(jù)報(bào)文中的偏移量综苔。和標(biāo)識(shí)符惩系、標(biāo)志位結(jié)合使用。
8.生存時(shí)間:占8位如筛。
生存時(shí)間由操作系統(tǒng)初始化蛆挫,每經(jīng)過(guò)一次轉(zhuǎn)發(fā),生存時(shí)間減1妙黍,如果生存時(shí)間為0悴侵,則該包丟棄。
生存時(shí)間是為了防止數(shù)據(jù)包在網(wǎng)絡(luò)中無(wú)休止發(fā)送拭嫁,占用網(wǎng)絡(luò)資源可免。
9.協(xié)議:占8位。常用的UDP的值是17做粤,TCP的值是6怕品。
10.首部校驗(yàn)和:占16位闯估。對(duì)IP數(shù)據(jù)包首部校驗(yàn)得到的值涨薪,校驗(yàn)和有具體的算法。
11.源IP地址:占32位
12.目的IP地址:占32位侠姑。
上面的內(nèi)容共占20個(gè)字節(jié),這些部分是固定的船老,每一個(gè)IP包的頭部都包含這些馍管,所以IP包頭的長(zhǎng)度至少20字節(jié)确沸。
下面的可選部分包含安全處理機(jī)制、記錄路徑桨菜、時(shí)間戳等信息,長(zhǎng)度為0-40字節(jié)霞掺。
再下面就是IP包的數(shù)據(jù)部分。IP包的數(shù)據(jù)包含TCP包骗灶、UDP包兩種喉恋。
#注意
下圖中的位指的是bit糊肤,上文中說(shuō)包的長(zhǎng)度是單位是字節(jié)馆揉,1字節(jié)=8位舷暮。
2.3.2 IP抓包實(shí)踐
2.4 TCP協(xié)議
http://www.reibang.com/p/e41a329ef353 (握手等過(guò)程參考這里)
2.4.1 TCP理論部分
TCP包的格式和IP包格式類似绩聘,同樣由頭部和數(shù)據(jù)兩部分組成机杜。
TCP包的長(zhǎng)度不固定,其中頭部長(zhǎng)度不固定陡叠,數(shù)據(jù)部分長(zhǎng)度不固定。
由IP部分的內(nèi)容可知兴溜,TCP包實(shí)際上就是IP包的數(shù)據(jù)部分拙徽。
#TCP頭部
1.源端口:占16位。
2.目的端口:占16位岛心。
3.序號(hào):sequence number,占32位。表示從發(fā)送端向接收端發(fā)送的字節(jié)流編號(hào)髓堪。
4.確認(rèn)號(hào):Acknowledgement number,占32位驶沼。表示接收端所期望接收到的下一序號(hào)商乎。
5.數(shù)據(jù)偏移:
占4位。數(shù)據(jù)偏移其實(shí)就是TCP包的頭部長(zhǎng)度抹凳,理論取值從0000-1111,最小為0幸冻,最大為15。
同IP頭部一樣碑定,TCP包的頭部長(zhǎng)度至少為20字節(jié),最多為60字節(jié)碘赖,且計(jì)算方式和IP頭部長(zhǎng)度的計(jì)算方式也一樣。
如果數(shù)據(jù)偏移的值為6劫哼,那么TCP包的頭部長(zhǎng)度為6 * 4 = 24。
6.保留值:占6位般码。目前沒(méi)用,為了之后新功能所保留券时。
7.6位標(biāo)志位。分別介紹:
>> URG:緊急標(biāo)志位炸枣,為1說(shuō)明緊急指針有效。
>> ACK:確認(rèn)標(biāo)志位侯养,為1說(shuō)明確認(rèn)序號(hào)有效。
>> PSH:值為1息尺,表示需要將數(shù)據(jù)立刻發(fā)送給應(yīng)用程序。
>> RST:值為1時(shí)炭懊,表示需要重連。
>> SYN:握手時(shí)使用父阻。值為1履婉,表示連接請(qǐng)求報(bào)文。
>> FIN:值為1時(shí)已烤,需要斷開(kāi)連接。
8.窗口大刑破:占16位,表示接收端的窗口大小星持,用于控制網(wǎng)絡(luò)流量速率。
9.校驗(yàn)和:占16位逻翁,和IP包頭部中的校驗(yàn)和作用一致。
10.緊急指針:占16位缠诅,和上面提到的URG字段結(jié)合使用管引。
11.可選部分谅将,包含窗口擴(kuò)大選項(xiàng)邦投、時(shí)間戳等志衣。最小為0狞洋,最大為40字節(jié)。
TCP包固定頭部20字節(jié)借嗽,可選部分在0-40字節(jié)之間恶导。
剩下的就是TCP包的數(shù)據(jù)部分。
2.4.2 TCP抓包實(shí)踐
2.4.3 TCP 三次握手 & 四次揮手
TCP 標(biāo)志位
1、SYN(synchronous建立聯(lián)機(jī))
2、ACK(acknowledgement 確認(rèn))
3企量、PSH(push傳送)
4、FIN(finish結(jié)束)
5恕汇、RST(reset重置)
6瘾英、URG(urgent緊急)
Sequence number(順序號(hào)碼)
Acknowledge number(確認(rèn)號(hào)碼)
TCP狀態(tài)
LISTEN - 偵聽(tīng)來(lái)自遠(yuǎn)方TCP端口的連接請(qǐng)求但惶;
SYN-SENT -在發(fā)送連接請(qǐng)求后等待匹配的連接請(qǐng)求阳啥;
SYN-RECEIVED - 在收到和發(fā)送一個(gè)連接請(qǐng)求后等待對(duì)連接請(qǐng)求的確認(rèn)斩狱;
ESTABLISHED- 代表一個(gè)打開(kāi)的連接所踊,數(shù)據(jù)可以傳送給用戶;
FIN-WAIT-1 - 等待遠(yuǎn)程TCP的連接中斷請(qǐng)求瓣蛀,或先前的連接中斷請(qǐng)求的確認(rèn);
FIN-WAIT-2 - 從遠(yuǎn)程TCP等待連接中斷請(qǐng)求改鲫;
CLOSE-WAIT - 等待從本地用戶發(fā)來(lái)的連接中斷請(qǐng)求;
CLOSING -等待遠(yuǎn)程TCP對(duì)連接中斷的確認(rèn)截歉;
LAST-ACK - 等待原來(lái)發(fā)向遠(yuǎn)程TCP的連接中斷請(qǐng)求的確認(rèn)咸作;
TIME-WAIT -等待足夠的時(shí)間以確保遠(yuǎn)程TCP接收到連接中斷請(qǐng)求的確認(rèn)记罚;
CLOSED - 沒(méi)有任何連接狀態(tài).
建立連接協(xié)議(三次握手)
>> 第一次握手:
客戶端發(fā)送syn包(syn=x)的數(shù)據(jù)包到服務(wù)器诬辈,并進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器確認(rèn)穿撮;
>> 第二次握手:
服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ack=x+1)栗柒,
同時(shí)自己也發(fā)送一個(gè)SYN包(syn=y),即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài)曙痘;
>> 第三次握手:
客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=y+1)茧痒,
此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài)桩蓉,完成三次握手。
握手過(guò)程中傳送的包里不包含數(shù)據(jù),三次握手完畢后样漆,客戶端與服務(wù)器才正式開(kāi)始傳送數(shù)據(jù)。
理想狀態(tài)下跪妥,TCP連接一旦建立落塑,在通信雙方中的任何一方主動(dòng)關(guān)閉連接之前仰挣,TCP連接都將被一直保持下去。
連接終止協(xié)議(四次握手)
client和server釋放資源
由于TCP連接是全雙工的洲愤,因此每個(gè)方向都必須單獨(dú)進(jìn)行關(guān)閉颓芭。
這個(gè)原則是當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個(gè)FIN來(lái)終止這個(gè)方向的連接。
收到一個(gè) FIN只意味著這一方向上沒(méi)有數(shù)據(jù)流動(dòng)柬赐,一個(gè)TCP連接在收到一個(gè)FIN后仍能發(fā)送數(shù)據(jù)亡问。
首先進(jìn)行關(guān)閉的一方將執(zhí)行主動(dòng)關(guān)閉,而另一方執(zhí)行被動(dòng)關(guān)閉。
TCP的連接的拆除需要發(fā)送四個(gè)包,因此稱為四次揮手(four-way handshake)贫堰。
客戶端或服務(wù)器均可主動(dòng)發(fā)起揮手動(dòng)作,在socket編程中壮不,任何一方執(zhí)行close()操作即可產(chǎn)生揮手操作缩功。
TCP協(xié)議的連接是全雙工連接,一個(gè)TCP連接存在雙向的讀寫通道甫男。
簡(jiǎn)單說(shuō)來(lái)是“先關(guān)讀效扫,后關(guān)寫”洽蛀,一共需要四個(gè)階段。
以客戶機(jī)發(fā)起關(guān)閉連接為例:
1.服務(wù)器讀通道關(guān)閉
2.客戶機(jī)寫通道關(guān)閉
3.客戶機(jī)讀通道關(guān)閉
4.服務(wù)器寫通道關(guān)閉
#詳細(xì)過(guò)程:
第一階段:
客戶機(jī)發(fā)送完數(shù)據(jù)之后未斑,向服務(wù)器發(fā)送一個(gè)FIN數(shù)據(jù)段诉瓦,序列號(hào)為x+2啄糙;
1.服務(wù)器收到FIN(x+2)后拐格,返回確認(rèn)段ACK,序列號(hào)為x+3铁材,關(guān)閉服務(wù)器讀通道油啤;
2.客戶機(jī)收到ACK(i+1)后,關(guān)閉客戶機(jī)寫通道;
(此時(shí),客戶機(jī)仍能通過(guò)讀通道讀取服務(wù)器的數(shù)據(jù)就轧,服務(wù)器仍能通過(guò)寫通道寫數(shù)據(jù))
第二階段:
服務(wù)器發(fā)送完數(shù)據(jù)之后魄宏,向客戶機(jī)發(fā)送一個(gè)FIN數(shù)據(jù)段航邢,序列號(hào)為y+1;
3.客戶機(jī)收到FIN(j)后扔嵌,返回確認(rèn)段ACK,序列號(hào)為y+2逸嘀,關(guān)閉客戶機(jī)讀通道回窘;
4.服務(wù)器收到ACK(y+2)后,關(guān)閉服務(wù)器寫通道帜乞。
這是標(biāo)準(zhǔn)的TCP關(guān)閉兩個(gè)階段,服務(wù)器和客戶機(jī)都可以發(fā)起關(guān)閉栏笆,完全對(duì)稱苞七。
https://blog.csdn.net/yangyangye/article/details/38851271 (詳解)
https://blog.csdn.net/zzhongcy/article/details/21992471
2.4.4 一些問(wèn)題
1.為什么建立連接協(xié)議是三次握手肋殴,而關(guān)閉連接卻是四次握手呢亏较?
#建立連接時(shí)
因?yàn)榉?wù)端的LISTEN狀態(tài)下的SOCKET當(dāng)收到SYN報(bào)文的建連請(qǐng)求后莺褒,
它可以把ACK和SYN(ACK起應(yīng)答作用,而SYN起同步作用)放在一個(gè)報(bào)文里來(lái)發(fā)送雪情。
#斷開(kāi)連接時(shí)
但關(guān)閉連接時(shí)遵岩,當(dāng)收到對(duì)方的FIN報(bào)文通知時(shí),它僅僅表示對(duì)方?jīng)]有數(shù)據(jù)發(fā)送給你了旺罢;
但未必你所有的數(shù)據(jù)都全部發(fā)送給對(duì)方了旷余,所以你可能未必會(huì)馬上會(huì)關(guān)閉SOCKET,
也即你可能還需要發(fā)送一些數(shù)據(jù)給對(duì)方之后,再發(fā)送FIN報(bào)文給對(duì)方來(lái)表示你同意現(xiàn)在可以關(guān)閉連接了扁达,
所以它這里的ACK報(bào)文和FIN報(bào)文多數(shù)情況下都是分開(kāi)發(fā)送的正卧。
2. 為什么不能用兩次握手進(jìn)行連接?
3次握手完成兩個(gè)重要的功能跪解,既要雙方做好發(fā)送數(shù)據(jù)的準(zhǔn)備工作(雙方都知道彼此已準(zhǔn)備好)炉旷,
也要允許雙方就初始序列號(hào)進(jìn)行協(xié)商,這個(gè)序列號(hào)在握手過(guò)程中被發(fā)送和確認(rèn)叉讥。
現(xiàn)在把三次握手改成僅需要兩次握手窘行,死鎖是可能發(fā)生的。
作為例子图仓,考慮計(jì)算機(jī)S和C之間的通信罐盔,假定C給S發(fā)送一個(gè)連接請(qǐng)求分組,
S收到了這個(gè)分組救崔,并發(fā)送了確認(rèn)應(yīng)答分組惶看。
按照兩次握手的協(xié)定,S認(rèn)為連接已經(jīng)成功地建立了六孵,可以開(kāi)始發(fā)送數(shù)據(jù)分組纬黎。
可是,C在 S的應(yīng)答分組在傳輸中被丟失的情況下劫窒,將不知道S是否已準(zhǔn)備好本今,
不知道S建立什么樣的序列號(hào),C甚至懷疑S是否收到自己的連接請(qǐng)求分組。
在這種情況下冠息,C認(rèn)為連接還未建立成功挪凑,將忽略S發(fā)來(lái)的任何數(shù)據(jù)分組,只等待連接確認(rèn)應(yīng)答分組铐达。
而S在發(fā)出的數(shù)據(jù)分組超時(shí)后岖赋,重復(fù)發(fā)送同樣的數(shù)據(jù)分組。這樣就形成了死鎖瓮孙。
就好比打電話, A打給B选脊, A要告訴B 杭抠,我打給你了, B要回應(yīng)給A聽(tīng)恳啥,OK偏灿,連接成功了;
然后B也要得到A的確認(rèn)钝的,才能開(kāi)始正式通話翁垂。
3.為什么TIME_WAIT狀態(tài)還需要等2MSL后才能返回到CLOSED狀態(tài)?
什么是2MSL硝桩?
MSL即Maximum Segment Lifetime沿猜,也就是報(bào)文最大生存時(shí)間,引用《TCP/IP詳解》中的話:
“它(MSL)是任何報(bào)文段被丟棄前在網(wǎng)絡(luò)內(nèi)的最長(zhǎng)時(shí)間碗脊√浼纾”
那么,2MSL也就是這個(gè)時(shí)間的2倍衙伶,當(dāng)TCP連接完成四個(gè)報(bào)文段的交換時(shí)祈坠,
主動(dòng)關(guān)閉的一方將繼續(xù)等待一定時(shí)間(2-4分鐘),即使兩端的應(yīng)用程序結(jié)束矢劲。
1)為什么需要這個(gè)2MSL呢赦拘?
>> 雖然雙方都同意關(guān)閉連接了,而且握手的4個(gè)報(bào)文也都協(xié)調(diào)和發(fā)送完畢芬沉,
按理可以直接回到CLOSED狀態(tài)(就好比從SYN_SEND狀態(tài)到ESTABLISH狀態(tài)那樣)躺同;
但是因?yàn)槲覀儽仨氁傧刖W(wǎng)絡(luò)是不可靠的枫吧,你無(wú)法保證你最后發(fā)送的ACK報(bào)文會(huì)一定被對(duì)方收到璧函,
因此對(duì)方處于LAST_ACK狀態(tài)下的SOCKET可能會(huì)因?yàn)槌瑫r(shí)未收到ACK報(bào)文,而重發(fā)FIN報(bào)文部凑,
所以這個(gè)TIME_WAIT狀態(tài)的作用就是用來(lái)重發(fā)可能丟失的ACK報(bào)文椭员。
>> 報(bào)文可能會(huì)被混淆车海,意思是說(shuō),其他時(shí)候的連接可能會(huì)被當(dāng)作本次的連接。
直接引用《The TCP/IP Guide》的說(shuō)法:
The second is to provide a “buffering period” between the end of this connection and any subsequent ones.
If not for this period, it is possible that packets from different connections could be mixed, creating confusion.
2)TIME_WAIT狀態(tài)存在的理由:
>> 可靠地實(shí)現(xiàn)TCP全雙工連接的終止
在進(jìn)行關(guān)閉連接四路握手協(xié)議時(shí)侍芝,最后的ACK是由主動(dòng)關(guān)閉端發(fā)出的研铆,如果這個(gè)最終的ACK丟失,
服務(wù)器將重發(fā)最終的FIN州叠,因此客戶端必須維護(hù)狀態(tài)信息允許它重發(fā)最終的ACK棵红。
如果不維持這個(gè)狀態(tài)信息,那么客戶端將響應(yīng)RST分節(jié)咧栗,
服務(wù)器將此分節(jié)解釋成一個(gè)錯(cuò)誤(在java中會(huì)拋出connection reset的SocketException)逆甜。
因而,要實(shí)現(xiàn)TCP全雙工連接的正常終止致板,必須處理終止序列四個(gè)分節(jié)中任何一個(gè)分節(jié)的丟失情況交煞,
主動(dòng)關(guān)閉 的客戶端必須維持狀態(tài)信息進(jìn)入TIME_WAIT狀態(tài)。
>> 允許老的重復(fù)分節(jié)在網(wǎng)絡(luò)中消逝
TCP分節(jié)可能由于路由器異常而“迷途”斟或,在迷途期間素征,TCP發(fā)送端可能因確認(rèn)超時(shí)而重發(fā)這個(gè)分節(jié),
迷途的分節(jié)在路由器修復(fù)后也會(huì)被送到最終目的地萝挤,這個(gè)原來(lái)的迷途分節(jié)就稱為lost duplicate御毅。
在關(guān)閉一個(gè)TCP連接后,馬上又重新建立起一個(gè)相同的IP地址和端口之間的TCP連接怜珍,
后一個(gè)連接被稱為前一個(gè)連接的化身 (incarnation)端蛆,那么有可能出現(xiàn)這種情況,
前一個(gè)連接的迷途重復(fù)分組在前一個(gè)連接終止后出現(xiàn)绘面,從而被誤解成從屬于新的化身欺税。
為了避免這個(gè)情 況,TCP不允許處于TIME_WAIT狀態(tài)的連接啟動(dòng)一個(gè)新的化身揭璃,
因?yàn)門IME_WAIT狀態(tài)持續(xù)2MSL晚凿,就可以保證當(dāng)成功建立一個(gè)TCP連接的時(shí)候,
來(lái)自連接先前化身的重復(fù)分組已經(jīng)在網(wǎng)絡(luò)中消逝瘦馍。
>> 對(duì)第二點(diǎn)的補(bǔ)充說(shuō)明.
防止lost duplicate對(duì)后續(xù)新建正常鏈接的傳輸造成破壞歼秽。
lost duplicate在實(shí)際的網(wǎng)絡(luò)中非常常見(jiàn),經(jīng)常是由于路由器產(chǎn)生故障情组,路徑無(wú)法收斂燥筷,
導(dǎo)致一個(gè)packet在路由器A,B院崇,C之間做類似死循環(huán)的跳轉(zhuǎn)肆氓。
IP頭部有個(gè)TTL,限制了一個(gè)包在網(wǎng)絡(luò)中的最大跳數(shù)底瓣,因此這個(gè)包有兩種命運(yùn):
要么最后TTL變?yōu)?谢揪,在網(wǎng)絡(luò)中消失;
要么TTL在變?yōu)?之前路由器路徑收斂,它憑借剩余的TTL跳數(shù)終于到達(dá)目的地拨扶。
但非车树蓿可惜的是TCP通過(guò)超時(shí)重傳機(jī)制在早些時(shí)候發(fā)送了一個(gè)跟它一模一樣的包,
并先于它達(dá)到了目的地患民,因此它的命運(yùn)也就注定被TCP協(xié)議棧拋棄缩举。
另外一個(gè)概念叫做incarnation connection,指跟上次的socket pair一摸一樣的新連接匹颤,
叫做incarnation of previous connection仅孩。
lost duplicate加上incarnation connection,則會(huì)對(duì)我們的傳輸造成致命的錯(cuò)誤印蓖。
大家都知道TCP是流式的杠氢,所有包到達(dá)的順序是不一致的,依靠序列號(hào)由TCP協(xié)議棧做順序的拼接另伍;
假設(shè)一個(gè)incarnation connection這時(shí)收到的seq=1000,
來(lái)了一個(gè)lost duplicate為seq=1000, len=1000,
則tcp認(rèn)為這個(gè)lost duplicate合法,并存放入了receive buffer绞旅,導(dǎo)致傳輸出現(xiàn)錯(cuò)誤摆尝。
通過(guò)一個(gè)2MSL TIME_WAIT狀態(tài),確保所有的lost duplicate都會(huì)消失掉因悲,避免對(duì)新連接造成錯(cuò)誤堕汞。
3)該狀態(tài)為什么設(shè)計(jì)在主動(dòng)關(guān)閉這一方:
(1)發(fā)最后ack的是主動(dòng)關(guān)閉一方
(2)只要有一方保持TIME_WAIT狀態(tài),就能起到避免incarnation connection在2MSL內(nèi)的重新建立晃琳,不需要兩方都有
4)對(duì)服務(wù)器的影響
當(dāng)某個(gè)連接的一端處于TIME_WAIT狀態(tài)時(shí)讯检,該連接將不能再被使用。
事實(shí)上卫旱,對(duì)于我們比較有現(xiàn)實(shí)意義的是人灼,這個(gè)端口將不能再被使用。
某個(gè)端口處于TIME_WAIT狀態(tài)(其實(shí)應(yīng)該是這個(gè)連接)時(shí)顾翼,
這意味著這個(gè)TCP連接并沒(méi)有斷開(kāi)(完全斷開(kāi))投放,那么,如果你bind這個(gè)端口适贸,就會(huì)失敗灸芳。
對(duì)于服務(wù)器而言,如果服務(wù)器突然crash掉了拜姿,那么它將無(wú)法在2MSL內(nèi)重新啟動(dòng)烙样,因?yàn)閎ind會(huì)失敗。
解決這個(gè)問(wèn)題的一個(gè)方法就是設(shè)置socket的SO_REUSEADDR選項(xiàng)蕊肥。
這個(gè)選項(xiàng)意味著你可以重用一個(gè)地址谒获。
5)如何正確對(duì)待2MSL TIME_WAIT
RFC要求socket pair在處于TIME_WAIT時(shí),不能再起一個(gè)incarnation connection。
但絕大部分TCP實(shí)現(xiàn)究反,強(qiáng)加了更為嚴(yán)格的限制寻定。
在2MSL等待期間,socket中使用的本地端口在默認(rèn)情況下不能再被使用精耐。
若A 10.234.5.5:1234和B 10.55.55.60:6666建立了連接狼速,A主動(dòng)關(guān)閉,
那么在A端只要port為1234卦停,無(wú)論對(duì)方的port和ip是什么向胡,都不允許再起服務(wù)。
顯而易見(jiàn)這是比RFC更為嚴(yán)格的限制惊完,RFC僅僅是要求socket pair不一致僵芹,
而實(shí)現(xiàn)當(dāng)中只要這個(gè)port處于TIME_WAIT,就不允許起連接小槐。
這個(gè)限制對(duì)主動(dòng)打開(kāi)方來(lái)說(shuō)是無(wú)所謂的拇派,因?yàn)橐话阌玫氖桥R時(shí)端口;
但對(duì)于被動(dòng)打開(kāi)方凿跳,一般是server件豌,就悲劇了,因?yàn)閟erver一般是熟知端口控嗜。
比如http茧彤,一般端口是80,不可能允許這個(gè)服務(wù)在2MSL內(nèi)不能起來(lái)疆栏。
解決方案是給服務(wù)器的socket設(shè)置SO_REUSEADDR選項(xiàng)曾掂,
這樣的話就算熟知端口處于TIME_WAIT狀態(tài),在這個(gè)端口上依舊可以將服務(wù)啟動(dòng)壁顶。
當(dāng)然珠洗,雖然有了SO_REUSEADDR選項(xiàng),但sockt pair這個(gè)限制依舊存在博助。
比如上面的例子险污,A通過(guò)SO_REUSEADDR選項(xiàng)依舊在1234端口上起了監(jiān)聽(tīng),
但這時(shí)我們?nèi)羰菑腂通過(guò)6666端口去連它富岳,TCP協(xié)議會(huì)告訴我們連接失敗蛔糯,原因?yàn)锳ddress already in use.
2.4.5 tcp長(zhǎng)連接和短連接
HTTP協(xié)議是基于請(qǐng)求/響應(yīng)模式的,因此只要服務(wù)端給了響應(yīng)窖式,本次HTTP連接就結(jié)束了蚁飒,
或者更準(zhǔn)確的說(shuō),是本次HTTP請(qǐng)求就結(jié)束了萝喘,根本沒(méi)有長(zhǎng)連接/短連接這一說(shuō)淮逻。
之所以說(shuō)HTTP分為長(zhǎng)連接和短連接琼懊,其實(shí)本質(zhì)上是說(shuō)的TCP連接。
TCP連接是一個(gè)雙向的通道爬早,它是可以保持一段時(shí)間不關(guān)閉的哼丈,
因此TCP連接才有真正的長(zhǎng)連接和短連接這一說(shuō)。
HTTP協(xié)議說(shuō)到底是應(yīng)用層的協(xié)議筛严,而TCP才是真正的傳輸層協(xié)議醉旦,只有負(fù)責(zé)傳輸?shù)倪@一層才需要建立連接。
TCP在真正的讀寫操作之前桨啃,server與client之間必須建立一個(gè)連接车胡,
當(dāng)讀寫操作完成后,雙方不再需要這個(gè)連接時(shí)它們可以釋放這個(gè)連接照瘾,
連接的建立通過(guò)三次握手匈棘,釋放則需要四次握手,
所以說(shuō)每個(gè)連接的建立都是需要資源消耗和時(shí)間消耗的析命。
TCP短連接
模擬一種TCP短連接的情況:
1.client 向 server 發(fā)起連接請(qǐng)求
2.server 接到請(qǐng)求主卫,雙方建立連接
3.client 向 server 發(fā)送消息
4.server 回應(yīng) client
5.一次讀寫完成,此時(shí)雙方任何一個(gè)都可以發(fā)起 close 操作
在步驟5中鹃愤,一般都是 client 先發(fā)起 close 操作队秩。當(dāng)然也不排除有特殊的情況。
從上面的描述看昼浦,短連接一般只會(huì)在 client/server 間傳遞一次讀寫操作!
#短連接的操作步驟是
建立連接——數(shù)據(jù)傳輸——關(guān)閉連接...建立連接——數(shù)據(jù)傳輸——關(guān)閉連接
TCP長(zhǎng)連接
再模擬一種長(zhǎng)連接的情況:
1.client 向 server 發(fā)起連接
2.server 接到請(qǐng)求筒主,雙方建立連接
3.client 向 server 發(fā)送消息
4.server 回應(yīng) client
5.一次讀寫完成关噪,連接不關(guān)閉
6.后續(xù)讀寫操作...
7.長(zhǎng)時(shí)間操作之后client發(fā)起關(guān)閉請(qǐng)求
#長(zhǎng)連接的操作步驟是
建立連接——數(shù)據(jù)傳輸...(保持連接)...數(shù)據(jù)傳輸——關(guān)閉連接
TCP長(zhǎng)/短連接的優(yōu)點(diǎn)和缺點(diǎn)
#長(zhǎng)連接
#優(yōu)點(diǎn):
可以省去較多的TCP建立和關(guān)閉的操作,減少浪費(fèi)乌妙,節(jié)約時(shí)間使兔。
對(duì)于頻繁請(qǐng)求資源的客戶來(lái)說(shuō),較適用長(zhǎng)連接藤韵。
#缺點(diǎn):
client與server之間的連接如果一直不關(guān)閉的話虐沥,會(huì)存在一個(gè)問(wèn)題,
隨著客戶端連接越來(lái)越多泽艘,server早晚有扛不住的時(shí)候欲险,這時(shí)候server端需要采取一些策略,
如關(guān)閉一些長(zhǎng)時(shí)間沒(méi)有讀寫事件發(fā)生的連接匹涮,這樣可以避免一些惡意連接導(dǎo)致server端服務(wù)受損天试;
如果條件再允許就可以以客戶端機(jī)器為顆粒度,限制每個(gè)客戶端的最大長(zhǎng)連接數(shù)然低,
這樣可以完全避免某個(gè)蛋疼的客戶端連累后端服務(wù)喜每。
#短連接
#優(yōu)點(diǎn):
對(duì)于服務(wù)器來(lái)說(shuō)管理較為簡(jiǎn)單务唐,存在的連接都是有用的連接,不需要額外的控制手段带兜。
#缺點(diǎn):
但如果客戶請(qǐng)求頻繁枫笛,將在TCP的建立和關(guān)閉操作上浪費(fèi)時(shí)間和帶寬。
TCP長(zhǎng)/短連接的應(yīng)用場(chǎng)景
#長(zhǎng)連接
多用于操作頻繁刚照,點(diǎn)對(duì)點(diǎn)的通訊刑巧,而且連接數(shù)不能太多情況。
每個(gè)TCP連接都需要三次握手涩咖,這需要時(shí)間海诲,如果每個(gè)操作都是先連接,
再操作的話那么處理速度會(huì)降低很多檩互,所以每個(gè)操作完后都不斷開(kāi)特幔,
再次處理時(shí)直接發(fā)送數(shù)據(jù)包就OK了,不用建立TCP連接闸昨。
例如:數(shù)據(jù)庫(kù)的連接用長(zhǎng)連接蚯斯,如果用短連接頻繁的通信會(huì)造成socket錯(cuò)誤,
而且頻繁的socket 創(chuàng)建也是對(duì)資源的浪費(fèi)饵较。
#短鏈接
像WEB網(wǎng)站的http服務(wù)一般都用短鏈接拍嵌,因?yàn)殚L(zhǎng)連接對(duì)于服務(wù)端來(lái)說(shuō)會(huì)耗費(fèi)一定的資源,
而像WEB網(wǎng)站這么頻繁的成千上萬(wàn)甚至上億客戶端的連接用短連接會(huì)更省一些資源循诉,
如果用長(zhǎng)連接横辆,而且同時(shí)有成千上萬(wàn)的用戶,如果每個(gè)用戶都占用一個(gè)連接的話茄猫,那可想而知吧狈蚤。
所以并發(fā)量大,但每個(gè)用戶無(wú)需頻繁操作情況下需用短連好划纽。
2.5 UDP協(xié)議
2.5.1 UDP基本理論
UDP數(shù)據(jù)傳輸?shù)奶攸c(diǎn)
#面向無(wú)連接
UDP 不需要與 TCP一樣在發(fā)送數(shù)據(jù)前進(jìn)行三次握手建立連接脆侮,UDP想發(fā)數(shù)據(jù)就直接發(fā)送了;
并且UDP只是數(shù)據(jù)報(bào)文的搬運(yùn)工勇劣,不會(huì)對(duì)數(shù)據(jù)報(bào)文進(jìn)行任何拆分和拼接操作靖避。
#不可靠
首先不可靠性體現(xiàn)在無(wú)連接上,通信都不需要建立連接比默,想發(fā)就發(fā)幻捏,這樣的情況肯定不可靠的;
并且收到什么數(shù)據(jù)就傳遞什么數(shù)據(jù)命咐,也不會(huì)備份數(shù)據(jù)粘咖,發(fā)送數(shù)據(jù)也不會(huì)關(guān)心對(duì)方是否已經(jīng)正確接收到數(shù)據(jù);
再者網(wǎng)絡(luò)環(huán)境時(shí)好時(shí)壞侈百,但是 UDP 因?yàn)闆](méi)有擁塞控制瓮下,一直會(huì)以恒定的速度發(fā)送數(shù)據(jù)翰铡;
即使網(wǎng)絡(luò)條件不好,也不會(huì)對(duì)發(fā)送速率進(jìn)行調(diào)整讽坏,這樣實(shí)現(xiàn)的弊端就是在網(wǎng)絡(luò)條件不好的情況下可能會(huì)導(dǎo)致丟包锭魔,
但是優(yōu)點(diǎn)也很明顯,在某些實(shí)時(shí)性要求高的場(chǎng)景(比如直播路呜、電話會(huì)議等)就需要使用 UDP 而不是 TCP迷捧;
#單播、多播胀葱、廣播功能
由于 UDP 不會(huì)建立連接漠秋,因此它可以給任何人傳遞數(shù)據(jù),
不止支持一對(duì)一的傳輸方式抵屿,同樣支持一對(duì)多庆锦、多對(duì)多、多對(duì)一的方式轧葛;
#UDP是面向報(bào)文的
發(fā)送方的UDP對(duì)應(yīng)用程序交下來(lái)的報(bào)文搂抒,在添加首部后就向下交付IP層.
UDP對(duì)應(yīng)用層交下來(lái)的報(bào)文,既不合并尿扯,也不拆分求晶,而是保留這些報(bào)文的邊界;
#頭部開(kāi)銷小衷笋,傳輸數(shù)據(jù)高效
UDP 的頭部開(kāi)銷小芳杏,只有八字節(jié),在傳輸數(shù)據(jù)報(bào)文時(shí)是比較高效的.在某些實(shí)時(shí)性要求高的場(chǎng)景辟宗,例如直播蚜锨、電話會(huì)議、媒體傳輸?shù)葓?chǎng)景經(jīng)常使用 UDP協(xié)議慢蜓;
相對(duì)TCP來(lái)說(shuō),UDP是無(wú)序郭膛、無(wú)狀態(tài)的晨抡,因此UDP包相對(duì)TCP包來(lái)說(shuō)要簡(jiǎn)單一些。
UDP包實(shí)際上也是IP包的數(shù)據(jù)部分则剃。
UDP包由頭部和數(shù)據(jù)兩部分組成耘柱,頭部長(zhǎng)度固定,數(shù)據(jù)部分長(zhǎng)度不固定棍现。
1.UDP頭部的長(zhǎng)度為固定8字節(jié)调煎。
>> 源端口:占16位
>> 目的端口:占16位
>> UDP長(zhǎng)度:包含頭部和數(shù)據(jù)包總長(zhǎng)度,注意和TCP包己肮、IP包的區(qū)別
>> 校驗(yàn)和:占16位士袄,同IP包悲关、TCP包校驗(yàn)和。
2.UDP的數(shù)據(jù)部分娄柳。
#注意
UDP頭部中UDP長(zhǎng)度寓辱,這個(gè)地方和TCP、IP包有明顯的區(qū)別赤拒。
因?yàn)閁DP包頭部長(zhǎng)度是固定8個(gè)字節(jié)秫筏,所以該部分的取值最小為1000。
2.5.2 UDP抓包實(shí)踐
wireshark
2.6 HTTP協(xié)議
http://www.reibang.com/p/e41a329ef353 (參考這里)
http://www.reibang.com/p/7c01759c28dd (https加密傳輸參考這里)
2.6.1 HTTP基本理論
2.6.2 HTTP抓包實(shí)踐
2.7 DNS協(xié)議
2.7.1 DNS基本理論
DNS包屬于UDP包挎挖,實(shí)際上这敬,DNS包是UDP包的數(shù)據(jù)部分。
DNS包同樣分為頭部和數(shù)據(jù)部分蕉朵,頭部長(zhǎng)度固定崔涂,數(shù)據(jù)部分長(zhǎng)度不固定。
#DNS數(shù)據(jù)包結(jié)構(gòu)
1.TranscationID:
會(huì)話標(biāo)識(shí)墓造,占2個(gè)字節(jié)堪伍。DNS請(qǐng)求報(bào)文和DNS應(yīng)到報(bào)文的TranscationID是相同的。
2.Flags:
占2個(gè)字節(jié)觅闽,包含多個(gè)標(biāo)志位:
2.1 QR:
占1位帝雇。0查詢報(bào)文,1響應(yīng)報(bào)文
2.2 Opcode:
占4位蛉拙。0標(biāo)準(zhǔn)查詢尸闸,1反向查詢,2服務(wù)器狀態(tài)查詢孕锄,3~15保留未用
2.3 AA:
占1位吮廉。為1,表示授權(quán)回答
2.4 TC:
占1位畸肆。為1宦芦,表示報(bào)文被截?cái)?2.5 RD:
占1位。0轴脐,表示客戶端期望域名解析服務(wù)器采用迭代的方式解析调卑;1表示客戶端期望域名解析服務(wù)器采用遞歸的方式解析
2.6 RA:占1位。
>> 0大咱,表示域名解析服務(wù)器采用迭代的方式解析恬涧;
>> 1表示域名服務(wù)器采用遞歸的方式解析
2.7 Zero:占3位。全0碴巾,保留位溯捆。
2.8 Rcode:占4位。響應(yīng)碼.
>> 0表示無(wú)差錯(cuò)厦瓢;
>> 1表示查詢格式錯(cuò)誤提揍;
>> 2表示服務(wù)器失效啤月;
>> 3表示域名錯(cuò)誤;
>> 4表示查詢沒(méi)有被執(zhí)行碳锈;
>> 5表示查詢被拒絕顽冶。
>> 6~15保留。
3.Questions:占2個(gè)字節(jié)售碳,表示查詢問(wèn)題區(qū)域的數(shù)量
4.Answers RRS:占2個(gè)字節(jié)强重,表示回答區(qū)域的數(shù)量
5.Authority RRs:占2個(gè)字節(jié),表示授權(quán)區(qū)域的數(shù)量
6.Additional RRs:占2個(gè)字節(jié)贸人,表示附加區(qū)域的數(shù)量
7.Quries:?jiǎn)栴}區(qū)域间景,長(zhǎng)度不固定,可以有多個(gè)艺智。
7.1 Name區(qū)域:就是查詢的域名倘要,如www.baidu.com,Name區(qū)域也有固定的格式十拣。
由于域名的長(zhǎng)度不固定封拧,所以name區(qū)域長(zhǎng)度不固定。
7.2 Type: 查詢類型夭问,占2個(gè)字節(jié)泽西。DNS有多種查詢類型:
查詢類型 助記符 功能
1 A 獲得IPv4地址
28 AAAA 獲得IPv6地址
15 MX 郵件服務(wù)器
2 NS 指定域名服務(wù)器
5 CNAME 將域名指向另一個(gè)域名時(shí)
7.3 Class,查詢類缰趋,通常為1捧杉,表示Internet數(shù)據(jù)。
8.Answers:回答區(qū)域秘血,長(zhǎng)度不固定味抖。
回答區(qū)域的格式和授權(quán)區(qū)域、附加區(qū)域的格式是類似的灰粮,因此仔涩,只介紹回答區(qū)域的格式。
8.1 Name:查詢的域名粘舟,同問(wèn)題區(qū)域的域名熔脂。
但是格式和問(wèn)題區(qū)域的域名不同,為了減小包大小蓖乘,當(dāng)包中出現(xiàn)重復(fù)域名的時(shí)候,回答區(qū)域的域名部分使用偏移量來(lái)表示韧骗。
當(dāng)使用偏移量來(lái)表示時(shí)嘉抒,占2個(gè)字節(jié)。不使用偏移量時(shí)袍暴,長(zhǎng)度不固定(和域名本身長(zhǎng)度有關(guān))些侍。
使用偏移量來(lái)表示時(shí)隶症,首字節(jié)固定為C0,用于識(shí)別岗宣,后面字節(jié)用于表示偏移量蚂会。
通過(guò)上面的介紹可知,DNS包的頭部固定占12字節(jié)耗式,頭部之后就是查詢問(wèn)題區(qū)域胁住,
查詢問(wèn)題區(qū)域的第一部分就是域名。因此刊咳,常見(jiàn)的偏移量是C00C彪见。
8.2 Type:同請(qǐng)求部分
8.3 Class:同請(qǐng)求部分
8.4 Time To Live:生存時(shí)間,占4個(gè)字節(jié)娱挨。實(shí)際上是客戶端緩存的時(shí)間余指。
通常情況,域名所對(duì)應(yīng)的IP不會(huì)經(jīng)常改變跷坝。
因此酵镜,為了提高網(wǎng)絡(luò)傳輸效率,可以將結(jié)果緩存柴钻,下次訪問(wèn)時(shí)跳過(guò)域名解析淮韭。
8.5 數(shù)據(jù)長(zhǎng)度:占2個(gè)字節(jié),下文數(shù)據(jù)部分的長(zhǎng)度顿颅。
8.6 數(shù)據(jù):不定長(zhǎng)缸濒。
9.Authoritative:同回答區(qū)域。
10.Additional:同回答區(qū)域粱腻。
2.7.2 DNS抓包實(shí)踐
3.網(wǎng)絡(luò)通信過(guò)程
使用集線器組成一個(gè)網(wǎng)絡(luò)
1)當(dāng)有多臺(tái)電腦需要組成一個(gè)網(wǎng)時(shí)庇配,那么可以通過(guò)集線器(Hub)將其鏈接在一起
2)一般情況下集線器的接口較少
3)集線器有個(gè)缺點(diǎn),它以廣播的方式進(jìn)行發(fā)送任何數(shù)據(jù)绍些,
即如果集線器接收到來(lái)自A電腦的數(shù)據(jù)本來(lái)是想轉(zhuǎn)發(fā)給B電腦捞慌,
如果此時(shí)它還連接著另外兩臺(tái)電腦C、D柬批,
那么它會(huì)把這個(gè)數(shù)據(jù)給每個(gè)電腦都發(fā)送一份啸澡,因此會(huì)導(dǎo)致網(wǎng)絡(luò)擁堵
使用交換機(jī)組成一個(gè)網(wǎng)絡(luò)
1)克服了集線器以廣播發(fā)送數(shù)據(jù)的缺點(diǎn),當(dāng)需要廣播的時(shí)候發(fā)送廣播氮帐,當(dāng)需要單播的時(shí)候又能夠以單播的方式進(jìn)行發(fā)送
2)它已經(jīng)替代了之前的集線器
3)企業(yè)中就是用交換機(jī)來(lái)完成多臺(tái)電腦設(shè)備的鏈接成網(wǎng)絡(luò)的
使用路由器連接多個(gè)網(wǎng)絡(luò)(組包, 拆包過(guò)程)
數(shù)據(jù)傳遞的過(guò)程, 是mac地址的交換與轉(zhuǎn)發(fā), 自始至終, 源ip和目的ip是固定的
路由器一般是默認(rèn)網(wǎng)關(guān), 具有數(shù)據(jù)轉(zhuǎn)發(fā)能力的設(shè)備
當(dāng)數(shù)據(jù)傳遞時(shí), 若一臺(tái)設(shè)備發(fā)送給另一臺(tái)設(shè)備時(shí):
會(huì)先執(zhí)行arp -a命令, 查看緩存中是否有另一個(gè)設(shè)備的mac地址(鏈路層),
若沒(méi)有, 則通過(guò)默認(rèn)網(wǎng)關(guān)進(jìn)行廣播, 廣播中有一類mac地址(FF:FF:FF:FF:FF:FF), 所有設(shè)備都能收到, 待鏈路層認(rèn)證通過(guò)后, 進(jìn)入ip層驗(yàn)證ip,
若ip認(rèn)證通過(guò), 則返回該設(shè)備的mac,
若ip認(rèn)證不通過(guò), 丟掉包, 不響應(yīng)
通信過(guò)程
1)在瀏覽器中輸入一個(gè)網(wǎng)址時(shí)嗅虏,需要將它先解析出ip地址來(lái)(DNS解析, 各電腦都有DNS地址:DNS服務(wù)器由國(guó)家管控)
2)當(dāng)?shù)玫絠p地址之后,瀏覽器以tcp的方式3次握手鏈接服務(wù)器
3)以tcp的方式發(fā)送http協(xié)議的請(qǐng)求數(shù)據(jù) 給 服務(wù)器
4)服務(wù)器tcp的方式回應(yīng)http協(xié)議的應(yīng)答數(shù)據(jù) 給瀏覽器
1)MAC地址:在設(shè)備與設(shè)備之間數(shù)據(jù)通信時(shí)用來(lái)標(biāo)記收發(fā)雙方(網(wǎng)卡的序列號(hào))
2)IP地址:在邏輯上標(biāo)記一臺(tái)電腦上沐,用來(lái)指引數(shù)據(jù)包的收發(fā)方向(相當(dāng)于電腦的序列號(hào))
3)網(wǎng)絡(luò)掩碼:用來(lái)區(qū)分ip地址的網(wǎng)絡(luò)號(hào)和主機(jī)號(hào)
4)默認(rèn)網(wǎng)關(guān):當(dāng)需要發(fā)送的數(shù)據(jù)包的目的ip不在本網(wǎng)段內(nèi)時(shí)皮服,就會(huì)發(fā)送給默認(rèn)的一臺(tái)電腦,稱為網(wǎng)關(guān)
5)集線器:已過(guò)時(shí),用來(lái)連接多態(tài)電腦龄广,缺點(diǎn):每次收發(fā)數(shù)據(jù)都進(jìn)行廣播硫眯,網(wǎng)絡(luò)會(huì)變的擁堵
6)交換機(jī):集線器的升級(jí)版,有學(xué)習(xí)功能知道需要發(fā)送給哪臺(tái)設(shè)備择同,根據(jù)需要進(jìn)行單播两入、廣播
7)路由器:連接多個(gè)不同的網(wǎng)段,讓他們之間可以進(jìn)行收發(fā)數(shù)據(jù)敲才,每次收到數(shù)據(jù)后裹纳,ip不變,但是MAC地址會(huì)變化
8)DNS:用來(lái)解析出IP(類似電話簿)
9)http服務(wù)器:提供瀏覽器能夠訪問(wèn)到的數(shù)據(jù)
10)網(wǎng)關(guān): 具有轉(zhuǎn)發(fā)數(shù)據(jù)能力的設(shè)備
(如192.168.1.2要發(fā)數(shù)據(jù)給192.168.2.2, 但二者不可直接通信,
可通過(guò)路由器A(有兩塊網(wǎng)卡, ip分別是192.168.1.3, 192.168.2.3),
ip192.168.1.2先轉(zhuǎn)給192.168.1.3, 然后192.168.1.3轉(zhuǎn)發(fā)給192.168.2.3, 然后192.168.2.3最終轉(zhuǎn)給192.168.2.2)
4. 常見(jiàn)問(wèn)題
4.1 TCP/IP協(xié)議簇粘包拆包問(wèn)題
http://www.reibang.com/p/209576915459
參考資源
http://www.reibang.com/p/9e63767c04e1 (各種協(xié)議包結(jié)構(gòu))
http://www.reibang.com/p/29868fb82890 (TCP三次握手四次揮手)