1. 程式人生 > >Http 請求到底有多慢

Http 請求到底有多慢

與寫p2p程式的同事商量了一下,檔案下載時怎樣去銜接p2p下載和向伺服器下載資料的這兩種方式,經過商量之後,決定用一個檔案來儲存整個檔案的分片資訊,比如每一片表示1400個位元組,那麼用一個byte陣列來儲存這些檔案片的下載資訊,0表示該檔案片沒有被下載,1 表示已經被下載了,這是p2p和http向伺服器請求檔案這兩種方式的一個公共的檔案。

p2p程式從byte陣列的0位置開始下載,接收到之後儲存檔案內容並且將byte[0] 賦值為1,以此類推,知道p2p下不起走為止,或是p2p的下載速度低於多少kb/s為止。

http怎樣與p2p銜接呢?這個公共的byte陣列中可以檢查出p2p到底下載到了哪裡! 就是從這個陣列的最後開始向前檢索,知道遇見第一個1,姑且把這個位置叫做p2pEnd,在0到p2pEnd之間去搜索沒有下載的檔案片,p2pEnd到byte.length 之間是沒有被下載過的檔案片。那麼對這兩段要怎樣處理呢?

第一段:0--p2pEnd:挨個檢索,可以根據byte陣列的指令碼計算中需要下載的檔案片是哪段檔案片,公式如下:

start = i*1400

end = start + 1399 

是的,通過Http的Get方法去獲取這1400個位元組的檔案片段,需要在http頭結點中設定header屬性Range即可!

這裡有一個坑! 比如我請求的是1400到2799這1400個位元組,當我接收的時候可能返回1147個位元組。具體是怎麼一回事,我也不太清楚,反正在程式中的話,可以檢測本此http請求是否返回了正確的檔案片長度。如果不正確的話,繼承本次的Range請求,直到獲得正確的檔案長度為止。等到檢索完從0到p2pEnd 時,p2p下載的漏洞基本上就補好了。

第二段:p2pEnd--byte.length :對於這段長度,我們可以採用整體下載的方式,為啥不想之前給p2p下載補漏洞的方式呢?也就是說,為啥不1400個位元組就請求一次呢?答案是http一應一答相當地廢時! 經過測試,本來頻寬可以達到150kb/s的快帶,用1400位元組一個個地下載的話,下載速度超不多20kb/s,多數時候在10kb/s以下。所有為了彌補這個缺陷,對於p2pEnd之後的檔案片段,就一次性放在httpGet的Range中,如Range:bytes=p2pEnd*1400 - (mContentLenght -1)

對於該HttpGet的迴應,也有一點技巧,為的就是給byte陣列賦值,掌握哪個檔案片被下載了,這裡給用於接收http response的inputsStream.read(buff)的buff byte陣列,其長度不能大於1400! 方便在每次接收資料之後就去給byte陣列賦值,大致可以這樣! byte[mReceivedLength / 1400] = 1 ,由於每次接收的長度不大於1400,所有每次接收的位元組不可能有1400個位元組的跨度,也就是說,不可能對byte陣列越角標賦值,所以下載一個就向byte陣列中寫入已經下載的標記,並且賦值10次或20次就把byte陣列中的資料儲存到配置檔案中去,以便儲存最新的下載記錄,如果不小心斷網了或斷點了,下次下載檔案的時候可以從這個配置檔案中去獲取,當前的檔案下載到了哪裡,應該從哪裡開始去更新下載的檔案。