這篇文章給大家介紹如何實現(xiàn)文件下載的斷點續(xù)傳以及TCP的基礎(chǔ)特性有哪些,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供彌勒網(wǎng)站建設(shè)、彌勒做網(wǎng)站、彌勒網(wǎng)站設(shè)計、彌勒網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、彌勒企業(yè)網(wǎng)站模板建站服務(wù),十載彌勒做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
從一個圖像傳輸項目說起
建連成功率,是網(wǎng)絡(luò)特別是無線網(wǎng)絡(luò)關(guān)注的重要指標(biāo)。對于客戶端demo,無論哪個平臺做網(wǎng)絡(luò)請求調(diào)用socket接口都能完成基本的數(shù)據(jù)收發(fā)流程。但是不做優(yōu)化的話,成功率基本在95%左右。系統(tǒng)調(diào)用接口基本是在有線網(wǎng)絡(luò)時代10Mbps的網(wǎng)速比較適用,要提升成功率,必須有良好的底層設(shè)計。
答主交付過淘寶ARbuy相關(guān)的業(yè)務(wù),相信有過相關(guān)項目經(jīng)驗的大致知道技術(shù)流程。技術(shù)核心就是物體的識別,如果識別模型放在APP側(cè),剩下的就是控制報文的交互,提升小包信令成功率基本各個大廠,微信淘寶支付寶美團(tuán)等都有自己的套路,大體思想類似,有空再展開。如果圖片放到服務(wù)端識別,那么數(shù)據(jù)包的上傳就需要特別設(shè)計了,并不是調(diào)用一下網(wǎng)絡(luò)接口就行了。
幾種基本思路
無線網(wǎng)絡(luò)相對有線網(wǎng)絡(luò)最大的特點就是高時延低帶寬,網(wǎng)絡(luò)狀態(tài)無法預(yù)估。我們先把網(wǎng)絡(luò)請求流程拆解來看:DNS查詢、TCP建連、TLS握手、數(shù)據(jù)發(fā)送、ack回應(yīng)。有關(guān)DNS優(yōu)化與TLS握手0rtt有空再展開,內(nèi)容太多,這里講講數(shù)據(jù)發(fā)送重傳和回應(yīng)超時設(shè)計。一般最有直觀感受的就是迅雷下載大文件的斷點續(xù)傳設(shè)計,答主之前也實現(xiàn)過FTP/TFTP協(xié)議,重點就是續(xù)傳記錄包的設(shè)計實現(xiàn)。各大客戶端的數(shù)據(jù)續(xù)傳分為下面幾種:
1、 續(xù)傳前查詢
發(fā)送大數(shù)據(jù)流失敗后,先查詢服務(wù)端接收點位置,得到回包后從下一序列號開始續(xù)傳。
這里需要有一個信令請求,一般采用RPC請求。
2、 上傳時回應(yīng)確認(rèn),斷連后重連時直接續(xù)傳,代表:著名的微信
這個協(xié)議代碼實現(xiàn)比較復(fù)雜,包括ACK回應(yīng)包的時間間隔、收到多少數(shù)據(jù)流進(jìn)行回應(yīng)等,需要根據(jù)網(wǎng)絡(luò)狀況進(jìn)行調(diào)整。大家可以參考TCP協(xié)議中的nagle算法與捎帶ACK特性,基本有所參考。
3、 斷連重新建連后客戶端直接重傳,服務(wù)端再通知客戶端還缺哪些,客戶端再快速重傳。代表:淘寶、天貓
協(xié)議設(shè)計很完善,但是動手敲過代碼調(diào)試過就知道里面有哪些坑,大家可以先想一下。
業(yè)務(wù)選擇
斷點續(xù)傳的基本方法就是上面幾種,選一個把超時設(shè)計好,就能做出一個比較好的方案了。
斷點續(xù)傳之所以麻煩,是因為客戶端發(fā)送數(shù)據(jù)包之后,無法得知服務(wù)端接收到了多少。上面的幾種解決方案從不同的思路解決了這個問題。
下面分析一下三種設(shè)計方案。第一種多了一個rtt,弱網(wǎng)環(huán)境下不是合適的選擇。初看第三種方案設(shè)計更好,但是內(nèi)核中TCP的實現(xiàn)是有緩沖區(qū)的,可以通過getsockopt查看,默認(rèn)為16k。對于上傳16k左右的文件,客戶端是可以全部扔到緩沖區(qū)的,這個時候斷連的話方案三就降級為先發(fā)送空包,等待服務(wù)端回包告訴客戶端接收到哪里了。對的,就是方案一,憑空多了一個rtt。并且如果超時設(shè)計不好的話,總體效果還比不上方案一。
再看方案二,無線網(wǎng)絡(luò)最大的特點就是抖動大,通過服務(wù)端及時不斷的給客戶端回應(yīng)確認(rèn),設(shè)計合適的等超時,可以及時識別TCP是否成了假連接(NAT表失效等情況)。當(dāng)然對于大型文件如迅雷下載,方案三是合適的。對于社交場景如微信等IM,對即時性要求較高的適合使用方案二。
TCP基礎(chǔ)特性
先看一下TCP的三次握手:
那么,為什么server不需要對報文3進(jìn)行確認(rèn)呢?換句話說,client怎么知道ack報文被對端收到了呢?這里有個約定:TCP僅對有效數(shù)據(jù)(包括SYN報文和FIN報文)進(jìn)行確認(rèn),不對ack報文進(jìn)行確認(rèn)。也就是報文3丟失了,對雙方后續(xù)通信不影響,這個不屬于有效信息,所以TCP中會有捎帶ACK的特性,也就是ACK會跟有效應(yīng)用層數(shù)據(jù)一起發(fā)給對端,如果一段時間內(nèi)沒有數(shù)據(jù)交互,那么200ms超時后會回一個單獨的ACK報文。那么報文2丟失了呢?服務(wù)端在發(fā)送SYNACK報文之后會啟動定時器,超時未收到報文3會進(jìn)行重傳。這里有一個SYN報文洪水攻擊,各家有各家的防范措施,前陣子淘寶還因為遭遇黑產(chǎn)上西溪派出所報案。有的服務(wù)端使用syncookie防范非法客戶端,但是對性能有一定影響,具體得結(jié)合業(yè)務(wù)優(yōu)化。服務(wù)端后臺針對ping、ICMP、DDOS攻擊的防范有空再展開。
這里大家可以考慮這樣一個場景:A向B約定下午兩點一起去教室自習(xí),A把信息發(fā)送給B(信息1),B回應(yīng)自身已經(jīng)收到信息(信息2),A向B回應(yīng)已經(jīng)收到回應(yīng)確認(rèn)(信息3)。我們看一下,A怎么確認(rèn)信息3已經(jīng)發(fā)送給B了呢?不需要A確認(rèn),因為如果B沒有收到信息3的話,會繼續(xù)重傳信息2。B怎么告訴A已經(jīng)收到了信息3呢?同樣不需要確認(rèn),后面有數(shù)據(jù)發(fā)送直接發(fā)送就行,這個例子里就是A和B直接去教室自習(xí)就行,信息2確認(rèn)收到后這個時候兩邊的信息狀態(tài)已經(jīng)同步了。
慢啟動與擁塞避免
發(fā)送方維持一個叫做擁塞窗口cwnd(congestion window)的狀態(tài)變量。擁塞窗口的大小取決于網(wǎng)絡(luò)的擁塞程度,并且動態(tài)地在變化。發(fā)送方讓自己的發(fā)送窗口等于擁塞窗口,另外考慮到接受方的接收能力,發(fā)送窗口可能小于擁塞窗口。
慢啟動值得就是一條TCP鏈接剛建立時不要一下發(fā)送大量數(shù)據(jù)導(dǎo)致網(wǎng)絡(luò)擁塞激增,而是由小到大根據(jù)反饋逐漸增大擁塞窗口。下面是連接剛建立時客戶端的發(fā)包行為,先不考慮接收端延遲ACK的情況:
可以看到擁塞窗口呈乘數(shù)增長。
為防止cwnd增長過大引起網(wǎng)絡(luò)擁塞,還需設(shè)置一個門限ssthresh變量。當(dāng)cwnd>ssthresh時,需采用擁塞避免算法。擁塞避免算法就是接收方每收到一個ack,就把cwnd加1。
快速重傳
當(dāng)發(fā)送端接收到三次重復(fù)確認(rèn)時,就可判斷對端尚未收到確認(rèn)字段后續(xù)的報文,可以進(jìn)行快速重傳而不必等rto定時器超時。
快速重傳之后就是快速恢復(fù),發(fā)送方會將ssthresh門限減半,考慮到發(fā)送方收到重復(fù)確認(rèn),說明此時網(wǎng)絡(luò)擁塞有所緩解,因此可以將擁塞窗口cwnd設(shè)置為ssthresh+3。為什么加3,是根據(jù)“數(shù)據(jù)包守恒”原則,同一時刻網(wǎng)絡(luò)管道中的數(shù)據(jù)包數(shù)量是恒定的,收到三個重復(fù)ack,說明有三個數(shù)據(jù)包離開了網(wǎng)絡(luò)管道。
發(fā)送端流量隨時間變化如下:
Linux內(nèi)核中使用的是cubic算法,基本原理與reno類似(reno本身也在演進(jìn)),有一個對現(xiàn)實網(wǎng)絡(luò)感知遲鈍的原因就是ssthresh門限值難以預(yù)估。Linux4.9已經(jīng)支持bbr,目前淘寶網(wǎng)絡(luò)客戶端已經(jīng)基于bbr進(jìn)行協(xié)議棧優(yōu)化,這塊有空寫寫。
關(guān)于如何實現(xiàn)文件下載的斷點續(xù)傳以及TCP的基礎(chǔ)特性有哪些就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。