??本文簡(jiǎn)要的分析了長(zhǎng)連接產(chǎn)生的背景以及所解決的問(wèn)題,并對(duì)比了keep-alive與心跳機(jī)制對(duì)長(zhǎng)連接?;畹挠绊懀詈笤敿?xì)的介紹了心跳?;畹膬蓚€(gè)關(guān)鍵因素--DHCP協(xié)議與NAT原理。如有不當(dāng)之處,歡迎批評(píng)和指正。
1.短連接,并行連接,持久連接與長(zhǎng)連接
(1) 短連接簡(jiǎn)介
??在互聯(lián)網(wǎng)發(fā)展過(guò)程中,最為普及的應(yīng)用就是HTTP超文本傳輸協(xié)議,而在早期--HTTP1.0的協(xié)議都是建立在TCP協(xié)議基礎(chǔ)上,其特點(diǎn)就是傳輸完數(shù)據(jù)后,立馬就釋放掉該TCP鏈接,所以就有了形象的短連接這個(gè)稱號(hào)。下圖形象的展示出了在一個(gè)事務(wù)的處理過(guò)程中,各個(gè)階段的處理時(shí)長(zhǎng):

??可以看到,與建立TCP連接,以及傳輸請(qǐng)求和響應(yīng)報(bào)文的時(shí)間相比,事務(wù)處理時(shí)間可能是很短的。短連接的性能瓶頸主要集中在如下幾個(gè)方面:
a.TCP連接的握手時(shí)延

??在發(fā)送數(shù)據(jù)之前,TCP要傳送兩個(gè)分組來(lái)建立連接(現(xiàn)代的TCP棧都允許客戶端在確認(rèn)分組中發(fā)送數(shù)據(jù)),此時(shí),SYN/SYN+ACK握手會(huì)產(chǎn)生一個(gè)可測(cè)量的時(shí)延。
b.延遲確認(rèn)
??每個(gè)TCP段都有一個(gè)序列號(hào)和數(shù)據(jù)完整性校驗(yàn)和。每個(gè)段的接收者收到完好的段時(shí),都會(huì)向發(fā)送者回送小的確認(rèn)分組。如果發(fā)送者沒(méi)有在指定的窗口時(shí)間內(nèi)收到確認(rèn)信息,發(fā)送者就認(rèn)為分組已被破壞或損毀,并重發(fā)數(shù)據(jù)。
??由于確認(rèn)報(bào)文很小,所以TCP允許在發(fā)往相同方向的輸出數(shù)據(jù)分組中對(duì)其進(jìn)行“捎帶”。TCP將返回的確認(rèn)信息與輸出的數(shù)據(jù)分組結(jié)合在一起,可以更有效地利用網(wǎng)絡(luò)。為了增加確認(rèn)報(bào)文找到同向傳輸數(shù)據(jù)分組的可能性,很多TCP棧都實(shí)現(xiàn)了一種“延遲確認(rèn)”算法。延遲確認(rèn)算法會(huì)在一個(gè)特定的窗口時(shí)間(通常是100~200毫秒)內(nèi)將輸出確認(rèn)存放在緩沖區(qū)中,以尋找能夠捎帶它的輸出數(shù)據(jù)分組。如果在那個(gè)時(shí)間段內(nèi)沒(méi)有輸出數(shù)據(jù)分組,就將確認(rèn)信息放在單獨(dú)的分組中傳送。
c.TCP慢啟動(dòng)
??TCP連接會(huì)隨著時(shí)間進(jìn)行自我“調(diào)諧”,起初會(huì)限制連接的最大速度,如果數(shù)據(jù)成功傳輸,會(huì)隨著時(shí)間的推移提高傳輸?shù)乃俣?,這種調(diào)諧被稱為TCP慢啟動(dòng),用于防止因特網(wǎng)的突然過(guò)載和擁塞。
??由于存在這種擁塞控制特性,所以新連接的傳輸速度會(huì)比已經(jīng)交換過(guò)一定量數(shù)據(jù)的、“已調(diào)諧”連接慢一些。
(2) 短連接的適用場(chǎng)景與優(yōu)缺點(diǎn)
??短連接多用于操作頻繁,點(diǎn)對(duì)點(diǎn)的通訊,而且連接數(shù)不能太多的情況。每個(gè)TCP連接的建立都需要三次握手,每個(gè)TCP連接的斷開(kāi)要四次揮手。適用于并發(fā)量大,但是每個(gè)用戶又不需頻繁操作的情況。
??但是在用戶需要頻繁操作的業(yè)務(wù)場(chǎng)景下(如新用戶注冊(cè),網(wǎng)購(gòu)提交訂單等),頻繁的使用短連接則會(huì)使性能時(shí)延產(chǎn)生疊加,如下如:

??因此就產(chǎn)生了一些列關(guān)于連接性能的改進(jìn)方案。
(3) 并行連接
??并行連接允許客戶端打開(kāi)多條連接,并行地執(zhí)行多個(gè)事務(wù),每個(gè)事務(wù)都有自己的TCP連接。這樣可以克服單條連接的空載時(shí)間和帶寬限制,時(shí)延可以重疊起來(lái),而且如果單條連接沒(méi)有充分利用客戶端的網(wǎng)絡(luò)帶寬,可以將未用帶寬分配來(lái)裝載其他對(duì)象。
??在PC時(shí)代,利用并行連接來(lái)充分利用現(xiàn)代瀏覽器的多線程并發(fā)下載能力的場(chǎng)景非常廣泛。
??但是并行連接也會(huì)產(chǎn)生一定的問(wèn)題,首先并行連接不一定更快,因?yàn)閹捹Y源有限,每個(gè)連接都會(huì)去競(jìng)爭(zhēng)這有限的帶寬,這樣帶來(lái)的性能提升就很小,甚至沒(méi)什么提升。另外打開(kāi)大量連接會(huì)消耗很多內(nèi)存資源,從而引發(fā)自身的性能問(wèn)題,因此每個(gè)瀏覽器,允許對(duì)每個(gè)域名的連接數(shù)一般是有上限的,如下圖所示:

(4) 持久連接
??HTTP1.0版本以后,允許HTTP設(shè)備在事務(wù)處理結(jié)束之后將TCP連接保持在打開(kāi)狀態(tài),以便為未來(lái)的HTTP請(qǐng)求重用現(xiàn)存的連接。在事務(wù)處理結(jié)束之后仍然保持在打開(kāi)狀態(tài)的TCP連接被稱為持久連接。非持久連接會(huì)在每個(gè)事務(wù)結(jié)束之后關(guān)閉。持久連接會(huì)在不同事務(wù)之間保持打開(kāi)狀態(tài),直到客戶端或服務(wù)器決定將其關(guān)閉為止。
??現(xiàn)在很多方案都會(huì)采用持久連接+新連接結(jié)合的方式,這種方式盡可能的減少了新建連接的浪費(fèi),同時(shí)當(dāng)現(xiàn)有連接沒(méi)有辦法滿足需求的時(shí)候,可以建立新連接滿足需求,比較靈活。
??持久連接的時(shí)間參數(shù),通常由服務(wù)器設(shè)定,比如nginx的keepalivetimeout,keepalive timout時(shí)間值意味著:一個(gè)http產(chǎn)生的tcp連接在傳送完最后一個(gè)響應(yīng)后,還需要hold住keepalive_timeout秒后,才開(kāi)始關(guān)閉這個(gè)連接;
??持久連接與并行連接相比,帶來(lái)的優(yōu)勢(shì)如下:
- 避免了每個(gè)事務(wù)都會(huì)打開(kāi)/關(guān)閉一條新的連接,造成時(shí)間和帶寬的耗費(fèi);
- 避免了TCP慢啟動(dòng)特性的存在導(dǎo)致的每條新連接的性能降低;
- 可打開(kāi)的并行連接數(shù)量實(shí)際上是有限的,持久連接則可以減少建立的連接的數(shù)量;
(5) 長(zhǎng)連接
??長(zhǎng)連接與持久連接本質(zhì)上非常的相似,持久連接側(cè)重于HTTP應(yīng)用層,特指一次請(qǐng)求結(jié)束之后,服務(wù)器會(huì)在自己設(shè)置的keepalivetimeout時(shí)間到期后才關(guān)閉已經(jīng)建立的連接。長(zhǎng)連接則是client方與server方先建立連接,連接建立后不斷開(kāi),然后再進(jìn)行報(bào)文發(fā)送和接收,直到有一方主動(dòng)關(guān)閉連接為止。
??長(zhǎng)連接的適用場(chǎng)景也非常的廣泛:
- 監(jiān)控系統(tǒng):后臺(tái)硬件熱插拔、LED、溫度、電壓發(fā)生變化等;
- IM應(yīng)用:收發(fā)消息的操作;
- 即時(shí)報(bào)價(jià)系統(tǒng):例如股市行情push等;
- 推送服務(wù):各種App內(nèi)置的push提醒服務(wù);
??像以上這些連接,如果每次操作都要建立連接然后再操作的話處理速度會(huì)降低,并且時(shí)效性也不高。通過(guò)長(zhǎng)連接,第一次連接上以后每次直接發(fā)送數(shù)據(jù)就可以了,不用再建立TCP連接。
2.長(zhǎng)連接?;?,Keep-Alive與心跳?;罴夹g(shù)
(1) 為何需要長(zhǎng)連接?;?/h3>
??上一節(jié)的分析可以看到,對(duì)于客戶端而言,使用TCP長(zhǎng)連接來(lái)實(shí)現(xiàn)業(yè)務(wù)的好處在于:在當(dāng)前連接可用的情況下,每一次請(qǐng)求都只是簡(jiǎn)單的數(shù)據(jù)發(fā)送和接受,免去了DNS解析,連接建立,TCP慢啟動(dòng)等時(shí)間,大大加快了請(qǐng)求的速度,同時(shí)也有利于接收服務(wù)器的實(shí)時(shí)消息。
??在使用TCP長(zhǎng)連接的業(yè)務(wù)場(chǎng)景下,保持長(zhǎng)連接的可用性非常重要。如果長(zhǎng)連接無(wú)法很好地保持,在連接已經(jīng)失效的情況下繼續(xù)發(fā)送請(qǐng)求會(huì)導(dǎo)致遲遲收不到響應(yīng)直到超時(shí),又需要一次連接建立的過(guò)程,其效率甚至還不如直接使用短連接。而連接保持的前提必然是檢測(cè)連接的可用性,并在連接不可用時(shí)主動(dòng)放棄當(dāng)前連接并建立新的連接。
(2) 心跳?;?/h3>
??App實(shí)現(xiàn)長(zhǎng)連接?;畹姆绞酵ǔJ遣捎?strong>應(yīng)用層心跳,通過(guò)心跳包的超時(shí)和其他條件(網(wǎng)絡(luò)切換)來(lái)執(zhí)行重連操作。心跳一般是指某端(絕大多數(shù)情況下是客戶端)每隔一定時(shí)間向?qū)Χ税l(fā)送自定義指令,以判斷雙方是否存活,因其按照一定間隔發(fā)送,類似于心跳,故被稱為心跳指令。
(3) Keep-Alive可否實(shí)現(xiàn)保活?
a.HTTP中的Keep-Alive
??實(shí)現(xiàn)HTTP/1.0 keep-alive連接的客戶端可以通過(guò)包含Connection:Keep-Alive首部請(qǐng)求將一條連接保持在打開(kāi)狀態(tài),如果服務(wù)器愿意為下一條請(qǐng)求將連接保持在打開(kāi)狀態(tài),就在響應(yīng)中包含相同的首部。如果響應(yīng)中沒(méi)有Connection: Keep-Alive首部,客戶端就認(rèn)為服務(wù)器不支持keep-alive,會(huì)在發(fā)回響應(yīng)報(bào)文之后關(guān)閉連接。HTTP/1.1以后Keep-Alive是默認(rèn)打開(kāi)的。
c.TCP中的Keep-Alive
??TCP協(xié)議的實(shí)現(xiàn)中,提供了KeepAlive報(bào)文,用來(lái)探測(cè)連接的對(duì)端是否存活。在應(yīng)用交互的過(guò)程中,可能存在以下幾種情況:
- 客戶端或服務(wù)器意外斷電,死機(jī),崩潰,重啟;
- 中間網(wǎng)絡(luò)已經(jīng)中斷,而客戶端與服務(wù)器并不知道;
??利用?;钐綔y(cè)功能,可以探知這種對(duì)端的意外情況,從而保證在意外發(fā)生時(shí),可以釋放半打開(kāi)的TCP連接。TCP?;顖?bào)文交互過(guò)程如下:

??雖然TCP提供了KeepAlive機(jī)制,但是并不能替代應(yīng)用層心跳?;?。原因主要如下:
- (1) Keep Alive機(jī)制開(kāi)啟后,TCP層將在定時(shí)時(shí)間到后發(fā)送相應(yīng)的KeepAlive探針以確定連接可用性。默認(rèn)時(shí)間為7200s(兩小時(shí)),失敗后重試10次,每次超時(shí)時(shí)間75s。顯然默認(rèn)值無(wú)法滿足移動(dòng)網(wǎng)絡(luò)下的需求;
- (2) 即便修改了(1)中的默認(rèn)值,也不能很好的滿足業(yè)務(wù)需求。TCP的KeepAlive用于檢測(cè)連接的死活而不能檢測(cè)通訊雙方的存活狀態(tài)。比如某臺(tái)服務(wù)器因?yàn)槟承┰驅(qū)е仑?fù)載超高,無(wú)法響應(yīng)任何業(yè)務(wù)請(qǐng)求,但是使用TCP探針則仍舊能夠確定連接狀態(tài),這就是典型的連接活著但業(yè)務(wù)提供方已死的狀態(tài),對(duì)客戶端而言,這時(shí)的最好選擇就是斷線后重新連接其他服務(wù)器,而不是一直認(rèn)為當(dāng)前服務(wù)器是可用狀態(tài),一直向當(dāng)前服務(wù)器發(fā)送些必然會(huì)失敗的請(qǐng)求。
- (3) socks代理會(huì)讓Keep Alive失效。socks協(xié)議只管轉(zhuǎn)發(fā)TCP層具體的數(shù)據(jù)包,而不會(huì)轉(zhuǎn)發(fā)TCP協(xié)議內(nèi)的實(shí)現(xiàn)細(xì)節(jié)的包。所以,一個(gè)應(yīng)用如果使用了socks代理,那么TCP的KeepAlive機(jī)制就失效了。
- (4) 部分復(fù)雜情況下Keep Alive會(huì)失效,如路由器掛掉,網(wǎng)線直接被拔除等;
??因此,KeepAlive并不適用于檢測(cè)雙方存活的場(chǎng)景,這種場(chǎng)景還得依賴于應(yīng)用層的心跳。應(yīng)用層心跳也具備著更大的靈活性,可以控制檢測(cè)時(shí)機(jī),間隔和處理流程,甚至可以在心跳包上附帶額外信息。
(4) 影響心跳頻率的關(guān)鍵因素
??通過(guò)上一節(jié)的分析可以看到應(yīng)用層心跳是檢測(cè)連接有效性以及判斷雙方是否存活的有效方式。但是心跳過(guò)于頻繁會(huì)帶來(lái)耗電和耗流量的弊病,心跳頻率過(guò)低則會(huì)影響連接檢測(cè)的實(shí)時(shí)性。業(yè)內(nèi)關(guān)于心跳時(shí)間的設(shè)置和優(yōu)化,主要基于如下幾個(gè)因素:
- 1.NAT超時(shí)--大部分移動(dòng)無(wú)線網(wǎng)絡(luò)運(yùn)營(yíng)商在鏈路一段時(shí)間沒(méi)有數(shù)據(jù)通訊時(shí),會(huì)淘汰 NAT表中的對(duì)應(yīng)項(xiàng),造成鏈路中斷;
- 2.DHCP租期--DHCP租期到了需要主動(dòng)續(xù)約,否則會(huì)繼續(xù)使用過(guò)期IP導(dǎo)致長(zhǎng)連接偶然的斷連;
- 3.網(wǎng)絡(luò)狀態(tài)變化--手機(jī)網(wǎng)絡(luò)和WIFI網(wǎng)絡(luò)切換、網(wǎng)絡(luò)斷開(kāi)和連上等情況有網(wǎng)絡(luò)狀態(tài)的變化,也會(huì)使長(zhǎng)連接變?yōu)闊o(wú)效連接;
??網(wǎng)絡(luò)狀態(tài)變化導(dǎo)致長(zhǎng)連接變?yōu)闊o(wú)效連接的原因很容易理解。但是NAT超時(shí)和DHCP租期的問(wèn)題對(duì)長(zhǎng)連接?;畲嬖诘挠绊懢蜕婕暗骄W(wǎng)絡(luò)協(xié)議底層的細(xì)節(jié)了。后續(xù)會(huì)對(duì)這兩個(gè)原理進(jìn)行相應(yīng)的分析。
3.DHCP原理淺析及其對(duì)心跳?;畹挠绊?/h2>
(1) DHCP協(xié)議簡(jiǎn)介
??DHCP協(xié)議全稱為Dynamic Host Configuration Protocol-- 動(dòng)態(tài)主機(jī)配置協(xié)議,主要用于在一個(gè)局域網(wǎng)里為主機(jī)動(dòng)態(tài)的分配IP地址。DHCP有三種分配IP地址方式:
- 自動(dòng)分配:DHCP給客戶端分配永久性的IP地址;
- 動(dòng)態(tài)分配:DHCP給客戶端分配的IP地址過(guò)一段時(shí)間后會(huì)過(guò)期,或者客戶端可以主動(dòng)釋放該地址(最常用的方式);
- 手動(dòng)配置:由用戶手動(dòng)為客戶端指定IP地址;
(2) DHCP工作流程詳解
??DHCP協(xié)議為客戶端分配IP的過(guò)程大致如下:

1.DHCP Discover
??DHCP客戶端(需要上網(wǎng)的設(shè)備)以廣播(因?yàn)榭蛻舳诉€不知道DHCP服務(wù)器的IP地址)的方式發(fā)送DHCP Discover包,來(lái)尋找DHCP服務(wù)器,即向地址255.255.255.255發(fā)送特定的廣播信息。網(wǎng)絡(luò)上每一臺(tái)安裝了TCP/IP協(xié)議的主機(jī)都會(huì)收到該廣播消息,但只有DHCP服務(wù)器才會(huì)做出響應(yīng)。


2.DHCP Offer
??在該階段,DHCP服務(wù)器提供IP地址。在網(wǎng)絡(luò)中接收到DHCP Discover包的DHCP服務(wù)器,都會(huì)做出響應(yīng)。這些DHCP服務(wù)器從尚未出租的IP地址中挑選一個(gè)給客戶端,向客戶端發(fā)送一個(gè)包含IP地址和其他設(shè)置的DHCP Offer包。


3.DHCP Request

??該階段需要DHCP客戶端選擇某臺(tái)DHCP服務(wù)器提供的IP地址,如上圖所示,可以看到3臺(tái)DHCP服務(wù)器都向客戶端發(fā)送了DHCP Offer,此時(shí),DHCP客戶端只能接受第一個(gè)收到的DHCP Offer包信息。然后,以廣播的方式回答一個(gè)DHCP Request請(qǐng)求信息,該信息中包含它所選定的DHCP服務(wù)器請(qǐng)求IP地址的內(nèi)容。

4.DHCP ACK
??確認(rèn)階段,DHCP服務(wù)器確認(rèn)所提供的的IP地址階段,告訴DHCP客戶端可以使用它所提供的IP地址。

(3) DHCP的續(xù)租問(wèn)題
??在DHCP ACK報(bào)文中,有3個(gè)關(guān)于續(xù)租時(shí)間相關(guān)的字段:
- Lease Time:
IP地址租約時(shí)間,超過(guò)了這個(gè)時(shí)間后,IP地址被DHCP服務(wù)器收回;- Renewal Time:
默認(rèn)為L(zhǎng)ease Time的1/2,表示客戶端需要進(jìn)行續(xù)約的時(shí)間。客戶端發(fā)送一個(gè)DHCP REQUEST消息給原始的DHCP服務(wù)器,并等待回復(fù)。DHCP服務(wù)器返回DHCP ACK則表示同意續(xù)期,客戶端更新自己的Renewal Time與Rebinding Time即可。- Rebinding Time:
默認(rèn)為L(zhǎng)ease Time的7/8,客戶端在續(xù)期失敗的情況下,Rebinding Time到期時(shí),會(huì)向局域網(wǎng)內(nèi)廣播發(fā)送一條DHCP REQUEST消息,如果還沒(méi)有DHCP服務(wù)器響應(yīng)直至租約Lease Time到期,將恢復(fù)到初始狀態(tài)。
??DHCP完成的狀態(tài)變遷流程如下:
(4) DHCP租期問(wèn)題對(duì)心跳?;畹挠绊?/h3>
??在設(shè)計(jì)心跳頻率時(shí),DHCP租期是一個(gè)不確定因素,但是原則是心跳的最大間隔應(yīng)該低于DHCP的租期時(shí)間。
??另外,在Android的一些版本上,存在DHCP租期到了不會(huì)主動(dòng)續(xù)約并且會(huì)繼續(xù)使用過(guò)期IP的bug。這個(gè)問(wèn)題導(dǎo)致的問(wèn)題表象是,在超過(guò)租期的某個(gè)時(shí)間點(diǎn)(沒(méi)有規(guī)律)會(huì)導(dǎo)致IP過(guò)期,老的TCP連接不能正常收發(fā)數(shù)據(jù)。并且系統(tǒng)沒(méi)有網(wǎng)絡(luò)變化事件,只有等應(yīng)用判斷主動(dòng)建立新的TCP連接才引起安卓設(shè)備重新向DHCP Server申請(qǐng)IP租用。詳情可見(jiàn)--Android 2.1 - 4.1.1 Allows DHCP Lease to Expire, Keeps Using IP Address。
4.NAT原理淺析及其對(duì)心跳?;畹挠绊?/h2>
(1) NAT技術(shù)產(chǎn)生的背景
??在網(wǎng)絡(luò)協(xié)議制定的初期設(shè)計(jì)網(wǎng)絡(luò)地址的時(shí)候,32bits位長(zhǎng)即2的32次冪臺(tái)終端設(shè)備連入互聯(lián)網(wǎng)已經(jīng)是一個(gè)非常大的數(shù)量了,再加上增加ip的長(zhǎng)度(即使是從4字節(jié)增到6字節(jié))對(duì)當(dāng)時(shí)設(shè)備的計(jì)算、存儲(chǔ)、傳輸成本也是相當(dāng)巨大的。因此IP地址設(shè)計(jì)為了32位,并且在早期所有需要上網(wǎng)的設(shè)備都有自己的IP地址,也就是說(shuō)那個(gè)時(shí)候沒(méi)有內(nèi)網(wǎng)和外網(wǎng)的區(qū)別,所有客戶端都是直接連接到互聯(lián)網(wǎng)的。
??進(jìn)入20世紀(jì)90年代之后,互聯(lián)網(wǎng)逐步向公眾普及,接入互聯(lián)網(wǎng)的設(shè)備數(shù)量也快速增長(zhǎng),如果還用原來(lái)的方法接入,過(guò)不了多久,可分配的地址就用光了。如果不能保證每臺(tái)設(shè)備有唯一不重復(fù)的地址,就會(huì)從根本上影響網(wǎng)絡(luò)包的傳輸,這是一個(gè)非常嚴(yán)重的問(wèn)題。如果任由這樣發(fā)展下去,不久的將來(lái),一旦固定地址用光,新的設(shè)備就無(wú)法接入了。在這個(gè)背景下NAT技術(shù)誕生了(雖然ipv6也是解決辦法,但始終普及不開(kāi)來(lái),而且未來(lái)到底ipv6夠不夠用仍是未知)。
(2) NAT技術(shù)的基本工作原理
a.NAT技術(shù)的本質(zhì)
??NAT技術(shù)主要是為了解決公網(wǎng)IP地址不足的問(wèn)題,所以才會(huì)采取這種地址轉(zhuǎn)換的策略。本質(zhì)上就是讓一群機(jī)器公用同一個(gè)IP,這樣就暫時(shí)解決了IP短缺的問(wèn)題。
b.私有地址與公有地址
??不同內(nèi)網(wǎng)之間是完全獨(dú)立的。內(nèi)網(wǎng)之間不會(huì)有網(wǎng)絡(luò)包流動(dòng),即使內(nèi)網(wǎng)A的某臺(tái)服務(wù)器和內(nèi)網(wǎng)B的某臺(tái)客戶端具有相同的IP地址也沒(méi)關(guān)系,因?yàn)樗鼈冎g不會(huì)進(jìn)行通信。只要在每個(gè)內(nèi)網(wǎng)自己的范圍內(nèi),能夠明確判斷網(wǎng)絡(luò)包的目的地就可以了,是否和其他局域網(wǎng)中的內(nèi)網(wǎng)地址重復(fù)無(wú)關(guān)緊要,只要每個(gè)局域網(wǎng)自己的網(wǎng)絡(luò)是相互獨(dú)立的,
就不會(huì)出現(xiàn)問(wèn)題。
??解決地址不足的問(wèn)題,利用的就是這樣的原理,即局域網(wǎng)的內(nèi)部設(shè)備的地址不一定要和其他局域網(wǎng)中的內(nèi)部設(shè)備地址不重復(fù)。這樣一來(lái),局域網(wǎng)的內(nèi)部設(shè)備就不需要分配固定地址了,從而大幅節(jié)省了IP地址。內(nèi)部設(shè)備分配IP地址的方式,就是通過(guò)上一節(jié)的DHCP協(xié)議進(jìn)行。內(nèi)網(wǎng)地址的分配有相應(yīng)的規(guī)則,規(guī)定某些地址是用于內(nèi)網(wǎng)的,這些地址叫作私有地址,而原來(lái)的固定地址則叫作公有地址。
??在內(nèi)網(wǎng)中可用作私有地址的范圍僅限以下這些:
- 10.0.0.0~10.255.255.255
- 172.16.0.0~172.31.255.255
- 192.168.0.0~192.168.255.255
??在制定私有地址規(guī)則時(shí),這些地址屬于公有地址中還沒(méi)有分配的范圍。換句話說(shuō),私有地址本身并沒(méi)有什么特別的結(jié)構(gòu),只不過(guò)是將公有地址中沒(méi)分配的一部分拿出來(lái)規(guī)定只能在內(nèi)網(wǎng)使用它們而已。
c.地址轉(zhuǎn)換(NAT)機(jī)制的加入
??當(dāng)內(nèi)網(wǎng)和互聯(lián)網(wǎng)之間需要傳輸包的時(shí)候,問(wèn)題就出現(xiàn)了,因?yàn)槿绻芏嗟胤蕉汲霈F(xiàn)相同的地址,包就無(wú)法正確傳輸了。因此當(dāng)公司內(nèi)網(wǎng)和互聯(lián)網(wǎng)連接的時(shí)候,需要采用下圖這樣的結(jié)構(gòu),即將公司內(nèi)網(wǎng)分成兩個(gè)部分,一部分是對(duì)互聯(lián)網(wǎng)開(kāi)放的服務(wù)器,另一部分是公司內(nèi)部設(shè)備。其中對(duì)互聯(lián)網(wǎng)開(kāi)放的部分分配公有地址,可以和互聯(lián)網(wǎng)直接進(jìn)行通信。相對(duì)地,內(nèi)網(wǎng)部分則分配私有地址,內(nèi)網(wǎng)中的設(shè)備不能和互聯(lián)網(wǎng)直接收發(fā)網(wǎng)絡(luò)包,而是通過(guò)一種特別的機(jī)制進(jìn)行連接,這個(gè)機(jī)制就叫地址轉(zhuǎn)換。

d.地址轉(zhuǎn)換(NAT)的基本原理
??地址轉(zhuǎn)換的基本原理是在轉(zhuǎn)發(fā)網(wǎng)絡(luò)包時(shí)對(duì)IP頭部中的IP地址和端口號(hào)進(jìn)行改寫,如下圖所示:TCP連接操作的第一個(gè)包被轉(zhuǎn)發(fā)到互聯(lián)網(wǎng)時(shí),會(huì)將發(fā)送方IP地址從私有地址改寫成公有地址。這里使用的公有地址是地址轉(zhuǎn)換設(shè)備的互聯(lián)網(wǎng)接入端口的地址。與此同時(shí),端口號(hào)也需要進(jìn)行改寫,地址轉(zhuǎn)換設(shè)備會(huì)隨機(jī)選擇一個(gè)空閑的端口。然后,改寫前的私有地址和端口號(hào),以及改寫后的公有地址和端口號(hào),會(huì)作為一組相對(duì)應(yīng)的記錄保存在地址轉(zhuǎn)換設(shè)備內(nèi)部的一張表(NAT表)中。

??改寫發(fā)送方IP地址和端口號(hào)之后,包就被發(fā)往互聯(lián)網(wǎng),最終到達(dá)服務(wù)器,然后服務(wù)器會(huì)返回一個(gè)包。服務(wù)器返回的包的接收包是原始包的發(fā)送方,因此返回的包的接收方就是改寫后的公有地址和端口號(hào)。這個(gè)公有地址其實(shí)是地址轉(zhuǎn)換設(shè)備的地址,因此這個(gè)返回包就會(huì)到達(dá)地址轉(zhuǎn)換設(shè)備。接下來(lái),地址轉(zhuǎn)換設(shè)備會(huì)從地址對(duì)應(yīng)表中通過(guò)公有地址和端口號(hào)找到相對(duì)應(yīng)的私有地址和端口號(hào),并改寫接收方信息,然后將包發(fā)給局域網(wǎng)的內(nèi)部設(shè)備,這樣包就能夠到達(dá)原始的發(fā)送方了。
e.為什么需要改寫端口號(hào)?
??早期的地址轉(zhuǎn)換機(jī)制是只改寫地址,不改寫端口號(hào)的。使用這種方法的前提是私有地址和公有地址必須一一對(duì)應(yīng),也就是說(shuō),有多少臺(tái)設(shè)備需要同時(shí)訪問(wèn)互聯(lián)網(wǎng),就需要多少個(gè)公有地址。訪問(wèn)動(dòng)作結(jié)束后可以刪除對(duì)應(yīng)表中的記錄,這時(shí)同一個(gè)公有地址可以分配給其他設(shè)備使用。
??后續(xù)隨著互聯(lián)網(wǎng)的發(fā)展,同一個(gè)局域網(wǎng)里的設(shè)備也越來(lái)越多。改寫端口號(hào)正是為了解決這個(gè)問(wèn)題??蛻舳艘环降亩丝谔?hào)本來(lái)就是從空閑端口中隨機(jī)選擇的,因此改寫了也不會(huì)有問(wèn)題。端口號(hào)是一個(gè)16比特的數(shù)值,總共可以分配出幾萬(wàn)個(gè)端口,因此如果用公有地址加上端口的組合對(duì)應(yīng)一個(gè)私有地址,一個(gè)公有地址就可以對(duì)應(yīng)幾萬(wàn)個(gè)私有地址,這種方法提高了公有地址的利用率。
(3) NAT技術(shù)帶來(lái)的弊端
??首先,NAT使IP會(huì)話的保持時(shí)效變短。因?yàn)镹AT表中的每一條記錄,在會(huì)話靜默的這段時(shí)間,NAT網(wǎng)關(guān)會(huì)進(jìn)行老化操作。這是任何一個(gè)NAT網(wǎng)關(guān)必須做的事情,因?yàn)镮P和端口資源有限,通信的需求無(wú)限,所以必須在會(huì)話結(jié)束后回收資源。通常TCP會(huì)話通過(guò)協(xié)商的方式主動(dòng)關(guān)閉連接,NAT網(wǎng)關(guān)可以跟蹤這些報(bào)文,但總是存在例外的情況,要依賴自己的定時(shí)器(NAT超時(shí)機(jī)制)去回收資源。通過(guò)NAT超時(shí)機(jī)制回收會(huì)帶來(lái)一個(gè)問(wèn)題,如果應(yīng)用需要維持連接的時(shí)間大于NAT網(wǎng)關(guān)的設(shè)置,通信就會(huì)意外中斷。因?yàn)榫W(wǎng)關(guān)回收相關(guān)轉(zhuǎn)換表資源以后,新的數(shù)據(jù)到達(dá)時(shí)就找不到相關(guān)的轉(zhuǎn)換信息,必須建立新的連接。
??其次,NAT在實(shí)現(xiàn)上將多個(gè)內(nèi)部主機(jī)發(fā)出的連接復(fù)用到一個(gè)IP上,這就使依賴IP進(jìn)行主機(jī)跟蹤的機(jī)制都失效了?;谟脩粜袨榈娜罩痉治鲆沧兊美щy,因?yàn)橐粋€(gè)IP被很多用戶共享,如果存在惡意的用戶行為,很難定位到發(fā)起連接的那個(gè)主機(jī)。NAT隱蔽了通信的一端,把簡(jiǎn)單的事情復(fù)雜化了。
??NAT一下對(duì)IP端到端模型產(chǎn)生了破壞。NAT通過(guò)修改IP首部的信息變換通信的地址。但是在這個(gè)轉(zhuǎn)換過(guò)程中只能基于一個(gè)會(huì)話單位。當(dāng)一個(gè)應(yīng)用需要保持多個(gè)雙向連接時(shí),麻煩就很大。NAT不能理解多個(gè)會(huì)話之間的關(guān)聯(lián)性,無(wú)法保證轉(zhuǎn)換符合應(yīng)用需要的規(guī)則。當(dāng)NAT網(wǎng)關(guān)擁有多個(gè)公有IP地址時(shí),一組關(guān)聯(lián)會(huì)話可能被分配到不同的公網(wǎng)地址,這通常是服務(wù)器端無(wú)法接受的。更為嚴(yán)重的是,當(dāng)公網(wǎng)側(cè)的主機(jī)要主動(dòng)向私網(wǎng)側(cè)發(fā)送數(shù)據(jù)時(shí),NAT網(wǎng)關(guān)沒(méi)有轉(zhuǎn)換這個(gè)連接需要的關(guān)聯(lián)表,這個(gè)數(shù)據(jù)包無(wú)法到達(dá)私網(wǎng)側(cè)的主機(jī)。這些反方向發(fā)送數(shù)據(jù)的連接總有應(yīng)用協(xié)議的約定或在初始建立的會(huì)話中進(jìn)行過(guò)協(xié)商。
(4) NAT超時(shí)機(jī)制對(duì)心跳?;?/h3>
??上一節(jié)已經(jīng)分析到,NAT超時(shí)機(jī)制會(huì)帶來(lái)一個(gè)問(wèn)題,如果應(yīng)用需要維持連接的時(shí)間大于NAT網(wǎng)關(guān)的設(shè)置,通信就會(huì)意外中斷。因?yàn)榫W(wǎng)關(guān)回收相關(guān)轉(zhuǎn)換表資源以后,新的數(shù)據(jù)到達(dá)時(shí)就找不到相關(guān)的轉(zhuǎn)換信息,必須建立新的連接。當(dāng)這個(gè)新數(shù)據(jù)是由公網(wǎng)側(cè)向私網(wǎng)側(cè)發(fā)送時(shí),就會(huì)發(fā)生無(wú)法觸發(fā)新連接建立,也不能通知到私網(wǎng)側(cè)的主機(jī)去重建連接的情況。這時(shí)候通信就會(huì)中斷,不能自動(dòng)恢復(fù)。即使新數(shù)據(jù)是從私網(wǎng)側(cè)發(fā)向公網(wǎng)側(cè),因?yàn)橹亟ǖ臅?huì)話表往往使用不同于之前的公網(wǎng)IP和端口地址,公網(wǎng)側(cè)主機(jī)也無(wú)法對(duì)應(yīng)到之前的通信上,導(dǎo)致用戶可感知的連接中斷。
??所以普遍的一個(gè)做法就是使用心跳?;?,在一段時(shí)間沒(méi)有數(shù)據(jù)需要發(fā)送時(shí),主動(dòng)發(fā)送一個(gè)NAT能感知到而又沒(méi)有實(shí)際數(shù)據(jù)的?;钕?-心跳,這么做的主要目的就是重置NAT的會(huì)話定時(shí)器。理想的情況下,客戶端應(yīng)當(dāng)以略小于NAT超時(shí)時(shí)間的間隔來(lái)發(fā)送心跳包。根據(jù)微信團(tuán)隊(duì)測(cè)試的一些數(shù)據(jù),一些常用網(wǎng)絡(luò)的NAT超時(shí)時(shí)間如下表所示:
| 地區(qū)/網(wǎng)絡(luò) | NAT超時(shí)時(shí)間 |
|---|---|
| 中國(guó)移動(dòng)3G和2G | 5分鐘 |
| 中國(guó)聯(lián)通2G | 5分鐘 |
| 中國(guó)電信3G | 大于28分鐘 |
| 美國(guó)3G | 大于28分鐘 |
| 臺(tái)灣3G | 大于28分鐘 |
5.小結(jié)
??本文簡(jiǎn)單的總結(jié)了一些短連接的劣勢(shì),以及幾種改進(jìn)的連接方案,并引出長(zhǎng)連接的概念和相關(guān)的使用場(chǎng)景,并詳細(xì)對(duì)比了keep-alive和心跳機(jī)制的不同之處,強(qiáng)調(diào)心跳機(jī)制對(duì)長(zhǎng)連接?;畹闹匾饬x。并對(duì)影響心跳時(shí)間的兩個(gè)關(guān)鍵--DHCP與NAT進(jìn)行了簡(jiǎn)單的介紹。現(xiàn)在動(dòng)態(tài)心跳的方案也越來(lái)越普及,網(wǎng)上已經(jīng)有不少文章做了相關(guān)的分享,本文參考文獻(xiàn)部分也有相關(guān)的鏈接。如有不當(dāng)之處,敬請(qǐng)批評(píng)指正。
參考文獻(xiàn)
1. TCP Keepalive HOWTO
2. 移動(dòng)端IM開(kāi)發(fā)需要面對(duì)的技術(shù)問(wèn)題
3. 為什么說(shuō)基于TCP的移動(dòng)端IM仍然需要心跳?;?/a>
4. DHCP General Operation and Client Finite State Machine
5. dhcp.figure
6. Android 2.1 - 4.1.1 Allows DHCP Lease to Expire, Keeps Using IP Address。
7. 《網(wǎng)絡(luò)是怎么連接的》--3.4.2節(jié):地址轉(zhuǎn)換的基本原理
8. 《HTTP權(quán)威指南》--第4章:連接管理
9. 前端性能--淺談?dòng)蛎l(fā)散與域名收斂
10. Tcp Keepalive 和 HTTP Keepalive詳解
11.Android端消息推送總結(jié):實(shí)現(xiàn)原理、心跳?;?、遇到的問(wèn)題等
12.P2P技術(shù)詳解(一):NAT詳解——詳細(xì)原理、P2P簡(jiǎn)介
13.知乎問(wèn)答--NAT與DHCP的區(qū)別
14.一種Android端IM智能心跳算法的設(shè)計(jì)與實(shí)現(xiàn)探討