程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 用Java設計下載軟件

用Java設計下載軟件

編輯:關於JAVA

本文介紹了如何使用Java編寫下載軟件並實現多現程下載

“網絡螞蟻”、Falshget等許多多線程下載軟件都是網友的必備工具,利用這些工具可以快速從服務器上下載比較大的文件,這些工具的工作特性是把服務器端的文件分成幾個段,每個段分別、同時進行下載。編寫這類程序,第一、必須對HTTP協議有較為充分的了解;第二、有效使用多線程編程手段在軟件上實現。

HTTP協議的簡介

HTTP協議是一種超文本傳輸協議(HypertextTransferProtocol),工作於網絡應用層,自1990年起廣泛應用於WWW的全球信息服務,HTTP協議的詳細說明可以在網上查閱RFC2518、RFC2616等文檔。

HTTP協議老的標准是HTTP/1.0,目前最通用的標准是HTTP/1.1。HTTP/1.1是在HTTP/1.0基礎上的升級,增加了一些功能,全面兼容HTTP/1.0。HTTP/1.0不支持文件斷點續傳,如果服務器使用HTTP/1.0,“網絡螞蟻”的任何多線程下載程序都只能按單線程下載;好在目前的Web服務器絕大多數都采用了HTTP/1.1,所以,下面將基於HTTP/1.1進行介紹。

HTTP協議的相關重要命令

基於HTTP的浏覽器浏覽網頁、下載文件時,工作原理類似客戶機/服務器模式:浏覽器向Web服務器發出一個HTTP請求行;Web服務器在收到有效的請求後,返回一個狀態行或多個響應標題、一個空白行和相關文檔。根據這一工作原理,下載程序必須實現向服務器發送請求和獲取服務器響應狀態的功能。

1.向服務器發送GET請求命令

一個HTTP請求由一個請求行、可選數目的請求標題、一個空白行,以及在POST情況下的一些額外的數據組成。請求行的格式是:

請求方法URIHTTP/版本號

GET命令是浏覽器常用的文檔請求方法,在程序中間使用

GETURIHTTP/1.1

向Web服務器發送請求行(行號3),Java代碼如下:

....

clIEntSocket=newSocket(host,port);//打開要下載文件服務器的Socket

outStream=newPrintStream(clIEntSocket.getOutputStream());

....

outStream.println(“GET”+uri+“HTTP/1.1”);

outStream.println(“Host:”+host);

outStream.println(“Accept:*/*”);

outStream.println(“Referer:”);

outStream.println();

....

注:第4行給出URL中的主機名和端口號,第5行說明客戶端接收所有MIME類型,第7行方送一個空白行,表明請求行結束。

2.獲取服務器響應狀態

在發送HTTP請求行以後,程序就可以讀取服務器的響應狀態了。HTTP響應狀態行包括:HTTP狀態碼和一些HTTP響應標題。

1)HTTP狀態碼

HTTP狀態碼格式是HTTP/版本信息的數字表示。狀態碼例子如下:

HTTP/1.0200OK//表示服務器支持HTTP/1.0協議,成功

HTTP/1.1200OK//表示服務器支持HTTP/1.1協議,成功

HTTP/1.0404NotFound//表示服務器支持HTTP/1.0協議,訪問文件沒有找到

在程序中間,如果讀到“HTTP/1.1200OK”這樣的字符串,表明欲下載文件存在、該服務器支持斷點續傳,可以使用多線程下載。如果讀到“HTTP/1.0200OK”這樣的字符串,表明欲下載文件存在、但該服務器不支持斷點續傳,只可以使用單線程下載。

.....

while((line=inStream.readLine())!=null)//將服務器響應狀態讀到line

........

if(line.substring(0,7).equals(“HTTP/1.”))//判斷是否支持HTTP/1.1

{if(line.charAt(7)==‘0’)

{

System.out.println(“serverusehttp/1.0”);

threadcount=1;

}

if(!(line.substring(9,12)).equals(“200”))//判斷請求是否成功

{System.out.println(“ERROR:”+line);

returnfalse;

}

}

2)讀取重要的響應標題,獲得要下載文檔的文件長度

如果HTTP狀態碼表明訪問成功,服務器會回送一些標題行,我們最關注的是Content-Length這一行,比如,如果服務器回送“Content-Length:1000”,表明請求文件的長度是1000字節,所以讀取這一行信息,可以得到文件的長度信息:

....

if(line.substring(0,15).equals(“Content-Length:”))

{filelength=Long.parseLong(line.substring(15).trim());

System.out.println(“filelength:”+filelength);

}

......

向服務器發送斷點續傳請求

如上所述,如果服務器支持HTTP/1.1,再次向服務器發送GET請求:

.....

outStream.println(“GET”+uri+“HTTP/1.1”);

outStream.println(“Host:”+host);

outStream.println(“Accept:*/*”);

outStream.println(“RANGE:bytes=”+(fileblocklength)*thisthreadid+“-”);

outStream.println();

.....

第4行是關鍵,“RANGE:bytes=”是HTTP/1.1新增內容,HTTP/1.0每次傳送文件都是從文件頭開始,即0字節處開始,“RANGE:bytes=XXXX”表示要求服務器從文件XXXX字節處開始傳送,這就是我們平時所說的斷點續傳!

分割文件,多線程下載

使用多線程編程技術,同時啟動多個線程,根據線程個數,計算文件分割位置,向服務器發送幾個不同的下載斷點,同時接受數據並寫入文件,就可以實現多線程下載了。

.....

raf=newRandomAccessFile(file,“rw”);//以隨機存取方式打開文件

.....

synchronized(raf)//按同步方式把各個線程得到數據分別寫入文件

{raf.seek(thisthreadid*(filelength/threadcount)+k*buflength);

raf.write(readbytes);

......

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved