Java Socket InputStream read()总是在结束之前返回-1

时间:2012-05-21 14:38:09

标签: java http sockets inputstream

我写下载应用。我想只使用java Socket来请求文件。所以我在我的套接字中写作HTTP协议规则。我的应用创建了一个连接,在阅读标题后,使用我的套接字read()的{​​{1}}方法。一切顺利。有时连接可能会丢失。但是我存储了我正在读取的字节,所以它再次创建了一个带有HTTP Ranged GET的新Socket并继续其工作。但是当下载即将完成时,我的意思是当剩余少于10 KB时,所有连接都将丢失,并且它(按计划)再次尝试打开新的Socket并继续其工作。它完全读取响应的标题,但在读取正文的任何​​字节之前,InputStream方法返回-1并且再次和它再次尝试打开一个新的Socket和read()剩余的字节,但问题仍然存在。关键是每次都可以完全读取响应头。我看到响应头的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 ...
    }
}

我不知道问题是什么,但不论它是什么,它几乎在流的末尾发生。 花了好几个小时后,我完全糊涂了。我将不胜感激任何帮助!

感谢名单

1 个答案:

答案 0 :(得分:2)

您是否在readHeaders()方法的InputStream之上分层缓冲读取器/流?我的猜测是你正在这样做,而且这个缓冲的流正在读取比预期更多的InputStream(因为它是缓冲)。从readHeaders()方法返回时,这些字节会丢失。

更新:

刚刚看到你的上一条评论。这正是你的问题。 BufferedReader占用了部分主体字节。