ネットワークプログラミング2

8002 ワード

HttpClient
getリクエストの送信
  • クライアントオブジェクトHttpClient hc=new DefaultHttpClient()を作成します.
  • get要求オブジェクトHttpGet hg=new HttpGet(path)を作成する.
  • get要求を送信、接続を確立し、応答ヘッダオブジェクトHttpResponse hr=hcを返す.execute(hg);
  • ステータスラインオブジェクトを取得し、ステータスコードを取得し、200であれば要求成功
    if(hr.getStatusLine().getStatusCode() == 200){
        //           
        InputStream is = hr.getEntity().getContent();
        String text = Utils.getTextFromStream(is);
    }
    
  • を示す.
    postリクエストの送信
        //         
        HttpClient client = new DefaultHttpClient();
        //    post    
        HttpPost hp = new HttpPost(path);
    
  • postオブジェクトにサーバに提出するデータ
    //               BasicNameValuePair   
    List<NameValuePair> parameters = new ArrayList<NameValuePair>();
    BasicNameValuePair bnvp = new BasicNameValuePair("name", name);
    BasicNameValuePair bnvp2 = new BasicNameValuePair("pass", pass);
    parameters.add(bnvp);
    parameters.add(bnvp2);
    //      ,    URL     
    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters, "utf-8");
    // post      
    hp.setEntity(entity);
    
  • を入れる.
    サードパーティ製フレームワーク–非同期HttpClientフレームワーク
    getリクエストの送信
        //     httpclient  
        AsyncHttpClient ahc = new AsyncHttpClient();
        //  get  
        ahc.get(path, new MyHandler());
    

    *AsyncHttpResponseHandlerの2つのメソッドの呼び出しタイミングに注意
        class MyHandler extends AsyncHttpResponseHandler{
    
            //http    ,    200,       
            @Override
            public void onSuccess(int statusCode, Header[] headers,
                    //responseBody             
                    byte[] responseBody) {
                Toast.makeText(MainActivity.this, new String(responseBody), 0).show();
    
            }
    
            //http    ,     200,       
            @Override
            public void onFailure(int statusCode, Header[] headers,
                    byte[] responseBody, Throwable error) {
                Toast.makeText(MainActivity.this, "     200", 0).show();
    
            }
    
        }
    

    postリクエストの送信
  • RequestParamsオブジェクトを使用して、携帯するデータ
    //    httpclient  
    AsyncHttpClient ahc = new AsyncHttpClient();
    //  RequestParams        
    RequestParams rp = new RequestParams();
    rp.add("name", name);
    rp.add("pass", pass);
    //  post  
    ahc.post(path, rp, new MyHandler());
    
  • をカプセル化する.
    マルチスレッドダウンロード
    原理:サーバーCPUが各スレッドに割り当てるタイムスライスは同じで、サーバー帯域幅は平均的に各スレッドに割り当てるので、クライアントが開くスレッドが多ければ多いほど、より多くのサーバー資源を奪うことができる.
    スレッドごとにダウンロードされるデータの数を決定
  • http要求をダウンロードアドレス
    String path = "http://192.168.1.102:8080/editplus.exe";     
    URL url = new URL(path);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setReadTimeout(5000);
    conn.setConnectTimeout(5000);
    conn.setRequestMethod("GET");                   
    
  • に送信する.
  • ファイルの合計長を取得し、一致する長さの一時ファイル
    if(conn.getResponseCode() == 200){
        //            
        int length = conn.getContentLength();
        //                getFileName(path):         
        RandomAccessFile raf = new RandomAccessFile(getFileName(path), "rwd");
        //         
        raf.setLength(length);
        raf.close();
    
  • を作成する.
  • スレッドがダウンロードするデータの数を決定する
        //            
        int blockSize = length / THREAD_COUNT;
    
  • 各スレッドのダウンロードデータの開始位置と終了位置の計算
        for(int id = 1; id <= 3; id++){
            //                    
            int startIndex = (id - 1) * blockSize;
            int endIndex = id * blockSize - 1;
            if(id == THREAD_COUNT){
                endIndex = length;
            }
    
            //    ,                   
            new DownLoadThread(startIndex, endIndex, id).start();
        }
    

    ダウンロードアドレスにリクエストを再送信し、開始位置から終了位置までのデータをリクエストする
        String path = "http://192.168.1.102:8080/editplus.exe";
    
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(5000);
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("GET");
    
        //          
        conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
        conn.connect();
    

    *要求されたデータをダウンロードし、一時ファイルに保存
        if(conn.getResponseCode() == 206){
            InputStream is = conn.getInputStream();
            RandomAccessFile raf = new RandomAccessFile(getFileName(path), "rwd");
            //             
            raf.seek(startIndex);
            byte[] b = new byte[1024];
            int len;
            while((len = is.read(b)) != -1){
                raf.write(b, 0, len);
            }
            raf.close();
        }
    

    ブレークポイント付きマルチスレッドダウンロード
  • はint変数を定義して各スレッドがダウンロードしたデータの全長を記録し、そのスレッドのダウンロード開始位置を加えると、得られた結果が次回のダウンロード時に、そのスレッドの開始位置となり、得られた結果をキャッシュファイル
    //              
    int total = 0;
    while((len = is.read(b)) != -1){
        raf.write(b, 0, len);
        total += len;
        //                    
        RandomAccessFile raf2 = new RandomAccessFile(threadId + ".txt", "rwd");
        raf2.write((startIndex + total + "").getBytes());
        raf2.close();
    }
    
  • に格納する.
  • 次回のダウンロード開始時に、キャッシュファイルの値を先に読み出す、そのスレッドの新しい開始位置
    FileInputStream fis = new FileInputStream(file);
    BufferedReader br = new BufferedReader(new InputStreamReader(fis));
    String text = br.readLine();
    int newStartIndex = Integer.parseInt(text);
    //             
    startIndex = newStartIndex;
    fis.close();
    
  • が得られる.
  • 3スレッドのダウンロードが完了すると、キャッシュファイル
    RUNNING_THREAD--;
    if(RUNNING_THREAD == 0){
        for(int i = 0; i <= 3; i++){
            File f = new File(i + ".txt");
            f.delete();
        }
    }
    
  • が削除されます.
    携帯電話版のブレークポイント継続マルチスレッドダウンロード
  • 先ほどのコードをそのまま貼れば使えますが、ファイルにアクセスする際のパスをAndroidのディレクトリに変更し、アクセスネットワークと外部ストレージのパス
  • を追加することを覚えています.
    ダウンロードの進捗状況を進捗バーで表示
  • ダウンロードファイルの全長を取得すると、プログレスバーの最大値
    //         
    pb.setMax(length);
    
  • が設定.
  • プログレスバーは3つのスレッドの全体的なダウンロードの進捗を表示する必要があるので、3つのスレッドはダウンロードするたびに、新しいダウンロードの長さをプログレスバーに追加します.
  • intグローバル変数を定義し、3つのスレッドの合計ダウンロード長
    int progress;
    
  • を記録する.
  • 更新進捗バー
    while((len = is.read(b)) != -1){
        raf.write(b, 0, len);
    
    
        //                  
        progress += len;
        pb.setProgress(progress);
    
  • ブレークダウンダウンロードのたびに、新しい開始位置からダウンロードを開始する、プログレスバーも新しい位置から表示を開始し、キャッシュファイルを読み出して新しいダウンロード開始位置を取得する際にも、プログレスバープログレス
    FileInputStream fis = new FileInputStream(file);
    BufferedReader br = new BufferedReader(new InputStreamReader(fis));
    String text = br.readLine();
    int newStartIndex = Integer.parseInt(text);
    
    //              ,           
    int alreadyDownload = newStartIndex - startIndex;
    //              
    progress += alreadyDownload;
    
  • を処理する.
    進行率を表示するテキスト・ボックスの追加
        tv.setText(progress * 100 / pb.getMax() + "%");
    

    HttpUtilsの使用
    HttpUtils自体はマルチスレッドブレークポイントの継続をサポートしており、非常に便利です
  • HttpUtilsオブジェクト
    HttpUtils http = new HttpUtils();
    
  • を作成する.
  • ダウンロードファイル
    http.download(url, //       
            target, //             
            true, //        
            true, //               ,            
            new RequestCallBack<File>() {//      
    
        //         
        @Override
        public void onSuccess(ResponseInfo<File> arg0) {
            tv.setText("    " + arg0.result.getPath());
        }
    
        //         ,        、      、      ,                 
        @Override
        public void onFailure(HttpException arg0, String arg1) {
            tv.setText("    " + arg1);
        }
    
        //           ,       
        @Override
        public void onLoading(long total, long current, boolean isUploading) {
            super.onLoading(total, current, isUploading);
            //        
            pb.setMax((int) total);
            //         
            pb.setProgress((int) current);
            tv_progress.setText(current * 100 / total + "%");
        }
    });