0

ダウンローダーアプリを書いています。ファイルを要求するために Java Socket のみを使用したい。そのため、HTTP プロトコルのルールと同じようにソケットに書き込みます。私のアプリは接続を作成し、ヘッダーを読み取った後、ソケットのread()メソッドを使用します。InputStreamすべてがうまくいきます。場合によっては接続が失われることがあります。しかし、私が読んでいたバイトを保存するので、再び HTTP Ranged GET で新しいソケットを作成し、その作業を続けます。しかし、ダウンロードが終了しようとしているとき、つまり残りが 10 KB 未満になると、すべての接続が失われ、(予定どおり) 新しいソケットを開いて作業を続行しようとします。応答のヘッダーを完全に読み取りますが、本文のバイトを読み取る前に、read()メソッドは -1 を返し、何度も何度も新しいソケットを開こうとし、read()残りのバイトですが、問題は解決しません。ポイントは、応答ヘッダーが完全に読み取られるたびにです。応答ヘッダーのContent-Length:フィールドは、ファイルの残りのバイトとまったく同じです。私は言及するのを忘れていました: 私は多くのサーバーから多くのファイルをチェックし、結果が同じであるため、私のコードには問題があります. コードは次のとおりです。

// Some fields:
int state;
long start, current, end;

// in a thread:
while (state != FINISHED) {
    if (state == DOWNLOADING) {
        try {
            // fill a new socket with Ranged GET [current, end]
            Socket s = initConnection();
            InputStream in = s.getInputStream();
            int readNo = 0;
            FileOutputStream out = getTempFile();
            byte[] buffer = new byte[1024];
            // read response headers successfully and prints them, request range is OK. a sample of its print is at the end of page
            readHeaders(in);
            while (state == DOWNLOADING && (readNo = in.read(buffer)) != -1) {                      
                current += readNo;
                out.write(buffer, 0, readNo);
            }
            if (readNo == -1) {
                // at nearly end of download always print this and values never changes, where usually they have 3000 byte difference
                System.out.println("**************> (" + current + " - " + end + ")");
            }
            if (currentByte == endByte) {
                state = FINISHED;
                //mergeParts();
                // code never reaches here
                dlInfo.checkAllPartsFinished();
            }
            out.flush();
            out.close();
            s.close();
        } catch (Exception e) {
            e.printStackTrace();
            state = ERROR;
            error = e.getMessage();
            errorRetry++;
        }
    } else if (state == PAUSED) {
        // ...
    } else ...
    }
}

何も変更されていないファイルの末尾にある応答ヘッダーのサンプル:

HTTP/1.1 206 Partial Content
Date: Mon, 21 May 2012 14:34:27 GMT
Server: Apache
Last-Modified: Sat, 21 Apr 2012 02:16:20 GMT
ETag: "4006d32e-f691e0-4be26fda00500"
Accept-Ranges: bytes
Content-Length: 7859
Content-Range: bytes 2012041-2019899/16159200
Connection: close
Content-Type: application/octet-stream

**************> (2012041 - 2019899)

何が問題なのかわかりませんが、それが何であれ、ストリームの終わり近くで発生します。何時間も費やした後、私は完全に混乱しています。どんな助けにも感謝します!

ありがとう

4

1 に答える 1

3

メソッドの InputStream の上に Buffered Reader/Stream を重ねていますreadHeaders()か? 私の推測では、あなたはこれを行っており、このバッファリングされたストリームは、予想よりも多くの InputStream を読み取っていると思います (バッファリングされているため)。これらのバイトは、メソッドから戻ったときに失われますreadHeaders()

アップデート:

ちょうどあなたの最後のコメントを見ました。それはまさにあなたの問題です。BufferedReader は本体バイトの一部を消費しています。

于 2012-05-21T14:53:25.910 に答える