用Java設計下載軟體思路

來源:互聯網
上載者:User

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

<iframe width="360" height="300" align="right"scrolling="No" frameborder="0" marginheight="0" marginwidth="0" SRC="http://images.chinabyte.com/adjs/iframe-pip/y-software-pip.html"></iframe>   HTTP 協議的簡介

  HTTP協議是一種超文字傳輸通訊協定 (HTTP)(Hypertext Transfer Protocol),工作於網路應用程式層,自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情況下的一些額外的資料群組成。請求行的格式是:

  要求方法 URI  HTTP/版本號碼

  GET 命令是瀏覽器常用的文檔要求方法,在程式中間使用

  GET URI  HTTP/1.1

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

<table width="100%" bgcolor="#FFFFFF"> <tr> <td>....
clientSocket = new Socket(host, port);//開啟要下載檔案伺服器的Socket
outStream = new PrintStream(clientSocket.getOutputStream());
....
outStream.println(“GET”+uri+“ HTTP/1.1”);
outStream.println(“Host:”+host);
outStream.println(“Accept:*/* ”);
outStream.println(“Referer:”);
outStream.println();
.... </td> </tr> </table>

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

  2.擷取伺服器響應狀態

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

  1) HTTP狀態代碼

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

  HTTP/1.0 200 OK // 表示伺服器支援HTTP/1.0 協議,成功

  HTTP/1.1 200 OK // 表示伺服器支援HTTP/1.1 協議,成功

  HTTP/1.0 404 Not Found // 表示伺服器支援HTTP/1.0 協議,訪問檔案沒有找到

  在程式中間,如果讀到“HTTP/1.1 200 OK”這樣的字串,表明欲下載檔案存在、該伺服器支援斷點續傳,可以使用多線程下載。如果讀到“HTTP/1.0 200 OK”這樣的字串,表明欲下載檔案存在、但該伺服器不支援斷點續傳,只可以使用單線程下載。

<table width="100%" bgcolor="#FFFFFF"> <tr> <td>.....
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(“server use http/1.0”);
threadcount=1;
}
if(!(line.substring(9,12)).equals(“200”)) //判斷請求是否成功
{ System.out.println(“ERROR:”+line);
return false;
}
} </td> </tr> </table>

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

  如果HTTP狀態代碼表明訪問成功,伺服器會回送一些標題列,我們最關注的是Content-Length 這一行,比如,如果伺服器回送“Content-Length:1000”,表明請求檔案的長度是1000位元組,所以讀取這一行資訊,可以得到檔案的長度資訊:

<table width="100%" bgcolor="#FFFFFF"> <tr> <td>....
if(line.substring(0,15).equals(“Content-Length:”) )
{ filelength=Long.parseLong(line.substring(15).trim());
System.out.println(“file length:” +filelength);
}
...... </td> </tr> </table>

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

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

<table width="100%" bgcolor="#FFFFFF"> <tr> <td>.....
outStream.println(“GET ”+uri+“HTTP/1.1 ”);
outStream.println(“Host:”+host);
outStream.println(“Accept:*/* ”);
outStream.println(“RANGE:bytes=”+(fileblocklength)*thisthreadid+“-”);
outStream.println();
..... </td> </tr> </table>

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

  分割檔案,多線程下載

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

<table width="100%" bgcolor="#FFFFFF"> <tr> <td>.....
raf=new RandomAccessFile(file,“rw”);//以隨機存取方式開啟檔案
.....
synchronized(raf) //按同步方式把各個線程得到資料分別寫入檔案
{ raf.seek(thisthreadid*(filelength/threadcount)+k*buflength);
raf.write(readbytes);
......
}
...... </td> </tr> </table> 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.