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