我正在寫下載程序。我只想用java Socket來請求一個文件。所以我按照HTTP協議規則在我的套接字中編寫。我的應用程序創建連接並在讀取標題後,使用我的套接字的InputStream
的read()
方法。一切順利。有時連接可能會丟失。但是我存儲了我正在讀取的哪個字節,因此它再次創建一個具有HTTP遠程GET的新Socket並繼續其工作。但是,當下載即將完成時,我的意思是當少於10 KB時,所有連接都將丟失,並再次(按計劃)嘗試打開新的套接字並繼續工作。它完全讀取響應的標題,但在讀取正文的任何字節之前,read()
方法返回-1並再次嘗試打開一個新的套接字和read()
其餘字節,但問題仍然存在。重點是每次響應標題可以完全讀取。並且我看到Content-Length:
響應頭字段正好是文件的其餘字節。我忘了提及:我的代碼有一個問題,因爲我檢查了很多服務器上的許多文件,結果是一樣的。這裏是代碼:Java Socket InputStream read()總是返回-1,結束之前
// 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)
我不知道是什麼問題,但不管是什麼,它發生在近流的結束。 我花了很多時間花了很多時間,我完全困惑。我會很感激任何幫助!
感謝名單
Whad有'readHeaders'嗎?你確定它沒有閱讀更多的信息嗎?它使用某種緩衝區嗎? –
在'readHeaders'中,我從套接字輸入流中創建了一個'BufferedReader'並且完全讀取到body。如果它不是確切的,它會在控制檯中打印一些內容! – MHM
@MHM:那就是你的問題!一個'BufferedReader'將**讀入一個緩衝區**,從中可以獲取內容。這意味着當'readHeaders'返回時,比標題更多的**將被從'InputStream'中讀取。這意味着你缺少的數據是*在開始處*,而不是在末尾。 –