0

我正在编写下载器应用程序。我只想使用 java Socket 来请求文件。所以我在我的套接字中写入 HTTP 协议规则。我的应用程序创建一个连接,并在读取标头后,使用我的套接字的read()方法InputStream。一切顺利。有时连接可能会丢失。但我存储了我正在读取的字节,所以它再次使用 HTTP Ranged GET 创建一个新的 Socket 并继续它的工作。但是当下载即将完成时,我的意思是当剩余不到 10 KB 时,所有连接都会丢失,它会再次(按计划)尝试打开新的 Socket 并继续它的工作。它完全读取响应的标头,但在读取正文的任何​​字节之前,read()方法返回 -1 并再次尝试打开一个新的 Socket 并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 之上分层了缓冲读取器/流readHeaders()?我的猜测是你正在这样做,并且这个缓冲流读取的 InputStream 比你预期的要多(因为它是缓冲的)。readHeaders()当您从该方法 返回时,这些字节会丢失。

更新:

刚看到你最后的评论。这正是你的问题。BufferedReader 正在消耗部分正文字节。

于 2012-05-21T14:53:25.910 回答