小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

基于TCp的數(shù)據(jù)包傳輸過(guò)程

 心不留意外塵 2017-04-13

http://blog.csdn.net/suiyuan19840208/article/details/22062657

2014

整個(gè)計(jì)算機(jī)網(wǎng)絡(luò)的實(shí)現(xiàn)體現(xiàn)為協(xié)議的實(shí)現(xiàn),TCP/IP協(xié)議是Internet的核心協(xié)議,HTTP協(xié)議是比TCP更高層次的應(yīng)用層協(xié)議。

HTTP(HyperText Transfer Protocol,超文本傳輸協(xié)議)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議。所有的WWW文件都必須遵守這個(gè)標(biāo)準(zhǔn)。設(shè)計(jì)HTTP的初衷是為了提供一種發(fā)布和接收HTML頁(yè)面的方法。

瀏覽器(Web Browser)負(fù)責(zé)與服務(wù)器建立連接,下載網(wǎng)頁(yè)(包括資源文件及JS腳本文件)到本地,并最終渲染出頁(yè)面。JS腳本文件運(yùn)行在客戶端,負(fù)責(zé)客戶端一些行為響應(yīng)或預(yù)處理,例如提交表單前的數(shù)據(jù)校驗(yàn)、鼠標(biāo)事件處理等交互。由此可見,瀏覽器(Browser)一方面充當(dāng)了C/S通信架構(gòu)C角色,另一方面它是HTML/JavaScript解析渲染引擎(Analyze Render Engine)。

在瀏覽器地址欄敲入“http://www.baidu.com/”,按下回車鍵,瀏覽器中呈現(xiàn)出百度首頁(yè)。這樣一種情景我們?cè)偈煜げ贿^(guò),本文通過(guò)wireshark抓取這一過(guò)程的TCP/IP數(shù)據(jù)包,結(jié)合TCP協(xié)議分析HTTP通信的基本流程。

MTU和MSS

本文用到的抓包工具為wireshark,它的前身是赫赫有名的Ethereal。wireshark以太網(wǎng)幀的封包格式為:

Frame = Ethernet Header + IP Header + TCP Header + TCP Segment Data

(1)Ethernet Header =14 Byte = Dst Physical Address(6 Byte)+ Src Physical Address(6 Byte)+ Type(2 Byte),以太網(wǎng)幀頭以下稱之為數(shù)據(jù)幀。

(2)IP Header =20 Byte(without options field),數(shù)據(jù)在IP層稱為Datagram,分片稱為Fragment。

(3)TCP Header = 20 Byte(without options field),數(shù)據(jù)在TCP層稱為Stream,分段稱為Segment(UDP中稱為Message)。

(4)54個(gè)字節(jié)后為TCP數(shù)據(jù)負(fù)載部分(Data Portion),即應(yīng)用層用戶數(shù)據(jù)。

Ethernet Header以下的IP數(shù)據(jù)報(bào)最大傳輸單位為MTU(Maximum Transmission Unit,Effect of short board),對(duì)于大多數(shù)使用以太網(wǎng)的局域網(wǎng)來(lái)說(shuō),MTU=1500。

TCP數(shù)據(jù)包每次能夠傳輸?shù)淖?a title="Hadoop知識(shí)庫(kù)" target="_blank" style="color:#df3434; font-weight:bold;">大數(shù)據(jù)分段為MSS,為了達(dá)到最佳的傳輸效能,在建立TCP連接時(shí)雙方協(xié)商MSS值,雙方提供的MSS值的最小值為這次連接的最大MSS值。MSS往往基于MTU計(jì)算出來(lái),通常MSS=MTU-sizeof(IP Header)-sizeof(TCP Header)=1500-20-20=1460。

這樣,數(shù)據(jù)經(jīng)過(guò)本地TCP層分段后,交給本地IP層,在本地IP層就不需要分片了。但是在下一跳路由(Next Hop)的鄰居路由器上可能發(fā)生IP分片!因?yàn)槁酚善鞯木W(wǎng)卡的MTU可能小于需要轉(zhuǎn)發(fā)的IP數(shù)據(jù)報(bào)的大小。這時(shí)候,在路由器上可能發(fā)生兩種情況:

(1).如果源發(fā)送端設(shè)置了這個(gè)IP數(shù)據(jù)包可以分片(May Fragment,DF=0),路由器將IP數(shù)據(jù)報(bào)分片后轉(zhuǎn)發(fā)。

(2).如果源發(fā)送端設(shè)置了這個(gè)IP數(shù)據(jù)報(bào)不可以分片(Don’t Fragment,DF=1),路由器將IP數(shù)據(jù)報(bào)丟棄,并發(fā)送ICMP分片錯(cuò)誤消息給源發(fā)送端。

關(guān)于MTU的探測(cè),參考《Path MTU discovery》。我們可以通過(guò)基于ICMP協(xié)議的ping命令來(lái)探測(cè)從本機(jī)出發(fā)到目標(biāo)機(jī)器上路由上的MTU,詳見下文。

TCP和UDP

在基于傳輸層(TCP/UDP)的應(yīng)用開發(fā)中,為了最后的程序優(yōu)化,應(yīng)避免端到端的任何一個(gè)節(jié)點(diǎn)上出現(xiàn)IP分片。TCP的MSS協(xié)商機(jī)制加上序列號(hào)確認(rèn)機(jī)制,基本上能夠保證數(shù)據(jù)的可靠傳輸。

UDP協(xié)議在IP協(xié)議的基礎(chǔ)上,只增加了傳輸層的端口(Source Port+Destination Port)、UDP數(shù)據(jù)包長(zhǎng)(Length = Header+Data)以及檢驗(yàn)和(Checksum)。因此,基于UDP開發(fā)應(yīng)用程序時(shí),數(shù)據(jù)包需要結(jié)合IP分片情況考慮。對(duì)于以太局域網(wǎng),往往取UDP數(shù)據(jù)包長(zhǎng)Length<=MTU-sizeof(IP Header)=1480,故UDP數(shù)據(jù)負(fù)載量小于或等于1472(Length-UDP Header);對(duì)于公網(wǎng),ipv4最小MTU為576,UDP數(shù)據(jù)負(fù)載量小于或等于536。

“向外”NAT在內(nèi)網(wǎng)和公網(wǎng)之間提供了一個(gè)“不對(duì)稱”橋的映射。“向外”NAT在默認(rèn)情況下只允許向外的session穿越NAT:從外向內(nèi)的的數(shù)據(jù)包都會(huì)被丟棄掉,除非NAT設(shè)備事先已經(jīng)定義了這些從外向內(nèi)的數(shù)據(jù)包是已存在的內(nèi)網(wǎng)session的一部分。對(duì)于一方在LAN,一方在WAN的UDP通信,鑒于UDP通信不事先建立虛擬鏈路,NAT后面的LAN通信方需先發(fā)送消息給WAN通信方以洞穿NAT,然后才可以進(jìn)行雙向通信,這即是常提到的“UDP打洞(Hole Punching)”問題。

TCP連接百度過(guò)程解析

下文對(duì)百度的完整抓包建立在不使用緩存的基礎(chǔ)上。如若主機(jī)存有百度站點(diǎn)的cookie和脫機(jī)緩存(Offline Cache),則不會(huì)再請(qǐng)求地址欄圖標(biāo)favicon.ico;請(qǐng)求/js/bdsug.js?v=1.0.3.0可能回應(yīng)“HTTP/1.1 304 Not Modified”??稍跒g覽器打開百度首頁(yè)后,Ctrl+F5強(qiáng)制刷新,不使用緩存,也可參考《瀏覽器清除緩存方法》。

以下為訪問百度過(guò)程,wireshark抓包數(shù)據(jù)。對(duì)于直接通過(guò)Ethernet聯(lián)網(wǎng)的機(jī)器,Wireshark Capture Filter為"host www.baidu.com";對(duì)于通過(guò)PPP over Ethernet(PPPoE)聯(lián)網(wǎng)的機(jī)器,Wireshark Capture Filter為"pppoes and host www.baidu.com"。以下抓包示例直接通過(guò)Ethernet聯(lián)網(wǎng)訪問百度的過(guò)程??牲c(diǎn)擊圖片超鏈接下載pcap文件,使用wireshark軟件查看。

為方便起見,以下將客戶端(瀏覽器)簡(jiǎn)稱為C,將服務(wù)器(百度)簡(jiǎn)稱為S。

 

1.TCP三次握手建立連接

“http://”標(biāo)識(shí)WWW訪問協(xié)議為HTTP,根據(jù)規(guī)則,只有底層協(xié)議建立連接之后才能進(jìn)行更高層協(xié)議的連接。在瀏覽器地址欄輸入地址后按下回車鍵的瞬間,C建立與S(機(jī)器名為www.baidu.com,DNS解析出來(lái)的IP為220.181.6.175)的TCP 80連接(HTTP默認(rèn)使用TCP 80端口)。

以下為三次握手建立TCP連接的數(shù)據(jù)包(Packet1-Packet3)。

1  192.168.89.125:5672 → 220.181.6.175:80   TCP(協(xié)議) 62(以太網(wǎng)幀長(zhǎng))

amqp > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460SACK_PERM=1

2  220.181.6.175:80 → 192.168.89.125:5672 TCP 62

http > amqp [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 SACK_PERM=1

3  192.168.89.125:5672 → 220.181.6.175:80   TCP 54

amqp > http [ACK] Seq=1 Ack=1 Win=65535 Len=0

三次握手建立TCP連接的流程如下:

    C(Browser)                                     S(www.baidu.com)

 1.  CLOSED                                             LISTEN

 2.  SYN-SENT     →<SEQ=0><CTL=SYN>               → SYN-RECEIVED

 3.  ESTABLISHED ← <SEQ=0><ACK=1><CTL=SYN,ACK> ← SYN-RECEIVED

 4.  ESTABLISHED → <SEQ=1><ACK=1><CTL=ACK>      → ESTABLISHED

3-Way Handshake for Connection Synchronization

三次握手的socket層執(zhí)行邏輯

S調(diào)用socket的listen函數(shù)進(jìn)入監(jiān)聽狀態(tài);C調(diào)用connect函數(shù)連接S:[SYN],S調(diào)用accept函數(shù)接受C的連接并發(fā)起與C方向上的連接:[SYN,ACK]。C發(fā)送[ACK]完成三次握手,connect函數(shù)返回;S收到C發(fā)送的[ACK]后,accept函數(shù)返回。

關(guān)于Seq和Ack

Seq即Sequence Number,為源端(source)的發(fā)送序列號(hào);Ack即Acknowledgment Number,為目的端(destination)的接收確認(rèn)序列號(hào)。在Wireshark Display Filter中,可使用tcp.seq或tcp.ack過(guò)濾。

在Packet1中,C:5672向S:80發(fā)送SYN握手包,Seq=0(relative sequence number);在Packet2中,S:80向C:5672發(fā)送ACK握手回應(yīng)包,Ack=1(relative sequence number),同時(shí)發(fā)送SYN握手包,Seq=0(relative sequence number);在Packet3中,C:5672向S:80發(fā)送ACK握手回應(yīng)包,Seq=1,Ack=1。

至此,Seq=1為C的Initial Sequence Number(ISN),后期某一時(shí)刻的Seq=ISN+累計(jì)發(fā)送量(cumulative sent);Ack=1為C的Initial Acknowledge Number(IAN),后期某一時(shí)刻的Ack=IAN+累計(jì)接收量(cumulative received)。對(duì)于S而言,Seq和Ack情同此理。

參考:《TCP Analyze Sequence Numbers》、《Understanding TCP Sequence and Acknowledgement Numbers

2.TCP獲取網(wǎng)站數(shù)據(jù)流程

連接建立后,下一步發(fā)送(“GET / HTTP/1.1”)請(qǐng)求(Request)HTML頁(yè)面,這里“/”表示S的默認(rèn)首頁(yè),“GET”為HTTP Request Method;“/”為Request-URI,這里為相對(duì)地址;HTTP/1.1表示使用的HTTP協(xié)議版本號(hào)為1.1。

以下為HTTP GET請(qǐng)求數(shù)據(jù)包(Packet4)。

4  192.168.89.125:5672 →220.181.6.175:80 HTTP 417

GET / HTTP/1.1

HTTP GET報(bào)文長(zhǎng)=417-54=363個(gè)字節(jié),其中Next sequence number: 364(relative sequence number)表示,若在規(guī)定的時(shí)間內(nèi)收到S響應(yīng)Ack=364,表明該報(bào)文發(fā)送成功,可以發(fā)送下一個(gè)報(bào)文(Seq=364);否則重傳(TCP Retransmitssion)。序列號(hào)確認(rèn)機(jī)制是TCP可靠性傳輸?shù)谋U稀?/span>

S(http)收到HTTP GET報(bào)文(共363個(gè)字節(jié)),向C(amqp)發(fā)送TCP確認(rèn)報(bào)文(Packet5)。

5  220.181.6.175:80 → 192.168.89.125:5672  TCP 60

http > amqp [ACK] Seq=1 Ack=364 Win=6432 Len=0

這里Seq=1,為S的ISN,意為已發(fā)送過(guò)SYN。Packet2中,Ack=1為S的IAN。這里的Ack-IAN=364-1=363表示S已經(jīng)從C接收到363個(gè)字節(jié),即HTTP GET報(bào)文。同時(shí),Ack=364也是S期待C發(fā)送的下一個(gè)TCP報(bào)文序列號(hào)(上面分析的Next sequence number)。

接下來(lái),S向C發(fā)送Http Response,根據(jù)HTTP協(xié)議,先發(fā)響應(yīng)頭(Response Header),再發(fā)百度首頁(yè)HTML文件。

Http Response Header報(bào)文(Packet6)如下。

6  220.181.6.175:80 → 192.168.89.125:5672  TCP 465

[TCP segment of a reassembled PDU]

其部分內(nèi)容如下:

======================================

HTTP/1.1 200 OK

……

Content-Length: 2139

Content-Type: text/html;charset=gb2312

Content-Encoding: gzip

======================================

S響應(yīng)C的“GET / HTTP/1.1”請(qǐng)求,先發(fā)送帶[PSH]標(biāo)識(shí)的411個(gè)字節(jié)的Http Response Header(Packet 6)。

TCP頭部[PSH]標(biāo)識(shí)置位,敦促C將緩存的數(shù)據(jù)推送給應(yīng)用程序,即先處理Http Response Header,實(shí)際上是一種“截流”通知。相應(yīng)C的socket調(diào)用send時(shí)在IPPROTO_TCP選項(xiàng)級(jí)別設(shè)置TCP_NODELAYTRUE禁用Nagle算法可以“保留發(fā)送邊界”,以防粘連。

盡管握手協(xié)商的MSS為1460,但服務(wù)器或者代理平衡服務(wù)器,每次發(fā)送過(guò)來(lái)的TCP數(shù)據(jù)最多只有1420個(gè)字節(jié)。可以使用ping -f -l size target_name命令向指定目標(biāo)target_name發(fā)送指定字節(jié)量的ICMP報(bào)文,其中-l size指定發(fā)送緩沖區(qū)的大小;-f則表示在IP數(shù)據(jù)報(bào)中設(shè)置不分片DF(Don’t Fragment),這樣便可探測(cè)出到目標(biāo)路徑上的MTU。

執(zhí)行“ping -f -l 1452www.baidu.com”的結(jié)果如下:

220.181.6.18的 Ping統(tǒng)計(jì)信息:

   數(shù)據(jù)包:已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失)

執(zhí)行“ping -f -l 1453www.baidu.com”的結(jié)果如下:

需要拆分?jǐn)?shù)據(jù)包但是設(shè)置 DF。

220.181.6.18的 Ping統(tǒng)計(jì)信息:

   數(shù)據(jù)包:已發(fā)送 = 4,已接收 = 0,丟失 = 4 (100% 丟失)

從以上ping結(jié)果可知,在不分片時(shí),從本機(jī)出發(fā)到百度的路由上能通過(guò)的最大數(shù)據(jù)量為1452,由此推算出MTU{local,baidu}=sizeof(IP Header)+ sizeof(ICMP Header)+sizeof(ICMP Data Portion)=20+8+1452=1480。

S調(diào)用socket的send函數(shù)發(fā)送2139個(gè)字節(jié)的Http Response Content(Packet 7、Packet 9),在TCP層將分解為兩段(segment)后再發(fā)出去。

7  220.181.6.175:80 → 192.168.89.125:5672  TCP 1474

[TCP segment of a reassembled PDU]

由“Content-Length: 2139”可知,HTML文件還有2139-(1474-54)=719個(gè)字節(jié)。但此時(shí),C已經(jīng)發(fā)送了確認(rèn)報(bào)文(Packet8)。

8  192.168.89.125:5672 →  220.181.6.175:80  TCP 54

amqp > http [ACK] Seq=364 Ack=1832 Win=65535 Len=0

Seq-ISN=364-1=363,表示C已經(jīng)發(fā)出了363個(gè)字節(jié),上邊已經(jīng)收到了S的確認(rèn)。Ack-IAN=1832-1=(465-54)+(1474-54),表示C至此已經(jīng)接收到S發(fā)來(lái)的1831個(gè)字節(jié)。

接下來(lái),C收到HTML文件剩余的719個(gè)字節(jié),報(bào)文(Packet9)如下。

9  220.181.6.175:80 → 192.168.89.125:5672  HTTP   773

HTTP/1.1 200 OK

至此,C收到S發(fā)送過(guò)來(lái)的全部HTTP響應(yīng)報(bào)文,即百度首頁(yè)HTML內(nèi)容(text/html)。

Packet6、Packet7和Packet9的ACK都是364,這是因?yàn)檫@三個(gè)segment都是針對(duì)Packet4的TCP響應(yīng)。S將百度首頁(yè)HTML文件(一個(gè)完整的HTTP報(bào)文)按照MSS分段提交給TCP層。在Wireshark中可以看到Packet9的報(bào)文中有以下reassemble信息:

[Reassembled TCP segments (2555 bytes): #6(411),#7(1420),#9(719)]

[Frame: 6, payload: 0-410(411 bytes)]

[Frame: 7, payload: 411-1830(1420 bytes)]

[Frame: 9, payload: 1831-2549(719 bytes)]

C(amqp)接收到百度首頁(yè)的HTML文件后,開始解析渲染。在解析過(guò)程中,發(fā)現(xiàn)頁(yè)面中含有百度的logo資源baidu_logo.gif,并且需要bdsug.js腳本

<img src="http://www.baidu.com/img/baidu_logo.gif" width="270" height="129" usemap="#mp">

{d.write('<script src=http://www.baidu.com/js/bdsug.js?v=1.0.3.0><//script>')}

于是上面那個(gè)連接(C:5672)繼續(xù)向S請(qǐng)求logo圖標(biāo)資源,報(bào)文(Packet10)如下。

10 192.168.89.125:5672 →  220.181.6.175:80  HTTP 492

GET /img/baidu_logo.gif HTTP/1.1

與此同時(shí),C(jms)新建一個(gè)連接(TCP 5673)向S請(qǐng)求js腳本文件。報(bào)文(Packet11)如下。

11 192.168.89.125:5673 →  220.181.6.175:80  TCP 62

jms > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1

(Packet12)Packet13、Packet14、Packet16和Packet17為對(duì)Packet10的TCP響應(yīng)(它們的Ack=802),在邏輯上它們是一個(gè)完整的TCP報(bào)文。其Http Response Content為圖片文件baidu_logo.gif。我們?cè)赪ireshark中可以看到Packet17的報(bào)文中有以下reassemble信息:

[Reassembled TCP segments (1801 bytes): #13(312),#14(1420),#16(28) ,#17(41)]

[Frame: 13, payload: 0-311(312 bytes)]

[Frame: 14, payload: 312-1731(1420 bytes)]

[Frame: 16, payload: 1732-1759(28 bytes)]

[Frame: 17, payload: 1760-1800(41 bytes)]

Packet11-Packet19-Packet20完成新連接的三次握手。然后,C(jms)發(fā)送“GET /js/bdsug.js?v=1.0.3.0 HTTP/1.1”報(bào)文(Packet21),以獲取bdsug.js腳本文件。

21 192.168.89.125:5673 →  220.181.6.175:80  HTTP 465

GET /js/bdsug.js?v=1.0.3.0 HTTP/1.1

(Packet22)Packet23、Packet24、Packet26和Packet27為對(duì)Packet21的TCP響應(yīng)(它們的Ack=412),在邏輯上它們是一個(gè)完整的TCP報(bào)文。其Http Response Content為腳本文件bdsug.js。我們?cè)赪ireshark中可以看到Packet27的報(bào)文中有以下reassemble信息:

[Reassembled TCP segments (3897 bytes): #23(310),#24(1420),#26(1420) ,#27(747)]

[Frame: 23, payload: 0-309(310 bytes)]

[Frame: 24, payload: 310-1729(1420 bytes)]

[Frame: 26, payload: 1730-3149(1420 bytes)]

[Frame: 27, payload: 3150-3896(747 bytes)]

通常,瀏覽器會(huì)自動(dòng)的搜索網(wǎng)站的根目錄,只要它發(fā)現(xiàn)了favicon.ico這個(gè)文件,就把它下載下來(lái)作為網(wǎng)站地址欄圖標(biāo)。于是,C(amqp)還將發(fā)起“GET /favicon.ico HTTP/1.1”請(qǐng)求網(wǎng)站地址欄圖標(biāo),見報(bào)文Packet29。

3.TCP四次揮手關(guān)閉連接

經(jīng)Packet28確認(rèn)收到了完整的japplication/javascript文件后,鏈路1(本地端口5673)使命結(jié)束,S關(guān)閉該鏈路,進(jìn)入四次揮手關(guān)閉雙向連接。

(Packet30)Packet31和Packet32為對(duì)Packet29的TCP響應(yīng)(它們的Ack=1201)。經(jīng)Packet33確認(rèn)收到了完整的image/x-icon文件后,鏈路2(本地端口5672)使命結(jié)束,S關(guān)閉該鏈路,進(jìn)入四次揮手關(guān)閉雙向連接。

   為什么握手是三次,而揮手是四次呢?這是因?yàn)槲帐謺r(shí),服務(wù)器往往在答應(yīng)建立連接時(shí),也建立與客戶端的連接,即所謂的雙向連接。所以,在Packet2中,服務(wù)器將ACK和SYN打包發(fā)出。揮手,即關(guān)閉連接,往往只是表明揮手方不再發(fā)送數(shù)據(jù)(無(wú)數(shù)據(jù)可發(fā)),而接收通道依然有效(依然可以接受數(shù)據(jù))。當(dāng)對(duì)方也揮手時(shí),則表明對(duì)方也無(wú)數(shù)據(jù)可發(fā)了,此時(shí)雙向連接真正關(guān)閉。

 

參考:

瀏覽器/網(wǎng)頁(yè)工作原理》《What really happens when you navigate to a URL

HTTP通信過(guò)程分析

究竟什么是HTTP連接

一次完整的HTTP通信步驟

SOCKET與TCP/IP與HTTP的關(guān)系

TCP連接、Http連接與Socket連接

TCP傳輸協(xié)議抓包經(jīng)驗(yàn)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多