基於HTTP的協議的網絡文件下載,工作原理建立在請求/響應模式(Request/Response)上:一個客戶端與服務器建立連接後,客戶端向Web服務器發出一個HTTP請求行;Web服務器在收到有效的請求後,返回一個狀態行或多個響應標題、一個空白行和相關文檔。HTTP協議使用的端口號,通常為80。開發基於http協議的網絡文件下載必須掌握HTTP協議,包括向服務器發送請求和獲取服務器響應狀態的過程。HTTP1.0協議不支持斷點續傳功能. 本文用java提供瞭一個簡單的實現.
1.HTTP協議工作方式
基於HTTP協議的客戶/服務器模式的信息交換過程,它分四個過程:建立連接、發送請求信息、獲取服務器響應狀態、關閉連接。其中較為復雜的過程是:發送請求信息、獲取服務器響應狀態.
1)向服務器發送請求信息
一個HTTP請求由一個請求行、可選數目的請求標題、一個空白行,以及在POST情況下的一些額外的數據組成。請求行的格式是:
Method Request-URI HTTP-Vsersion CRLF
Method表示請求方法,如GET和POST
Request-URI標識瞭要請求的資源,
HTTP-Version表示請求的HTTP協議版本,
CRLF表示回車換行。
HTTP請求報文格式如下:
HTTP Command: //方法字段(GET方法,POST方法)
URI: //URL字段,發送請求至保存該網站的服務器。
HTTP Version: //http協議版本字段
Accept: //指示可被接受的請求回應的介質類型范圍列表。
Accept-Language: //限制瞭請求回應中首選的語言為簡體中文,否則使用默認值。
Accept-Encoding: //限制瞭回應中可接受的內容編碼值
User-Agent: //定義用戶代理,即發送請求的瀏覽器類型
Host: //定義瞭目標所在的主機
Connection: //告訴服務器使用連接類型
2)獲取服務器響應狀態
在發送HTTP請求行以後,程序就可以讀取服務器的響應狀態瞭。HTTP響應狀態行包括:HTTP 狀態碼和一些HTTP響應標題。
HTTP回應報文
HTTP Version: HTTP/1.1 //服務器用的是HTTP/1.1版本
HTTP Status: 200 //請求成功,信息可以讀取,包含在響應的報文中
Date: //響應報文的時間
Server: //響應報文的服務器
X-Powered-By: //表明運行環境
Set- cookie: //
Vary: //
Content-Length: //表明實體的長度
Connection: //告訴客戶機在報文發送完畢後連接的狀態
Content-Type: //表明實體中的對象類型(html文檔)
Binary Data: //二進制數據
狀態碼表示響應類型,常用的有:
1×× 保留
2×× 表示請求成功地接收
3×× 為完成請求客戶需進一步細化請求
4×× 客戶錯誤
5×× 服務器錯誤
在程序中間,如果讀到“HTTP/1.1 200 OK”這樣的字符串,表明欲下載文件存在、該服務器支持斷點續傳,可以使用多線程下載。如果讀到“HTTP/1.0 200 OK”這樣的字符串,表明欲下載文件存在、但該服務器不支持斷點續傳,隻可以使用單線程下載。
2.實現代碼
Java代碼
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
public class TestDownFile {
public static void main(String[] args){
String sURL ="http://localhost:8080/hrproject/book.rar";
int nStartPos=0;
int nRead=0;
String sName="book.rar";
String sPath="e:\\temp";
try {
URL url = new URL(sURL);
//打開連接
HttpURLConnection httpConnection = (HttpURLConnection) url
.openConnection();
//獲得文件長度
long nEndPos =getFileSize(sURL);
RandomAccessFile oSavedFile= new RandomAccessFile(sPath+"\\"+sName, "rw");
httpConnection.setRequestProperty("User-Agent", "Internet Explorer");
String sProperty = "bytes=" + nStartPos + "-";
//告訴服務器book.rar這個文件從nStartPos字節開始傳
httpConnection.setRequestProperty("RANGE", sProperty);
System.out.println(sProperty);
InputStream input = httpConnection.getInputStream();
byte[] b = new byte[1024];
//讀取網絡文件,寫入指定的文件中
while ((nRead = input.read(b, 0, 1024)) > 0
&& nStartPos < nEndPos ) {
oSavedFile.write(b, 0, nRead);
nStartPos += nRead;
}
httpConnection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
// 獲得文件長度
public static long getFileSize(String sURL) {
int nFileLength = -1;
try {
URL url = new URL(sURL);
HttpURLConnection httpConnection = (HttpURLConnection) url
.openConnection();
httpConnection.setRequestProperty("User-Agent", "Internet Explorer");
int responseCode = httpConnection.getResponseCode();
if (responseCode >= 400) {
System.err.println("Error Code : " + responseCode);
return -2; // -2 represent access is error
}
String sHeader;
for (int i = 1;; i++) {
sHeader = httpConnection.getHeaderFieldKey(i);
if (sHeader != null) {
if (sHeader.equals("Content-Length")) {
nFileLength = Integer.parseInt(httpConnection
.getHeaderField(sHeader));
break;
}
} else
break;
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(nFileLength);
return nFileLength;
}
}
作者“海納百川,有容乃大”