我爲Java中的HTTP消息編寫了一個標記器。它有一個方法nextToken()
,它應該返回一個包含收到的整個HTTP消息的字符串。問題是消息在預期的主體大小被讀取之前結束。爲什麼我的HTTP消息在正文大小達到Content-Length頭中規定的大小之前結束?
我將輸入流一直讀到主體的開頭。然後,我嘗試從流中讀取n字節,其中n是在Content-Length報頭中聲明的主體的字節大小。問題在於在while
循環中,行charsRead = in.read(buffer)
因爲輸入流中沒有更多輸入而被阻塞。但它發生在讀取之前字節。
示例:對於大小爲12,493的主體,當需要讀取更多675個字節時會阻塞。
輸入流使用UTF-8,因此每個字節都編碼爲一個char
。
/* Somewhere else in the code:
InputStreamReader _isr =
new InputStreamReader(clientSocket.getInputStream(), "UTF-8")
*/
BufferedReader in = new BufferedReader(_isr);
StringBuilder tmp = new StringBuilder();
String line = "";
boolean body = false;
int bodylen = -1;
for (;;) {
line = in.readLine();
if (line == null)
break;
if (line.equals("")) { /* We've reached the body */
body = true;
break;
}
tmp.append(line + "\r\n");
if ((bodylen == -1) && (line.contains("Content-Length:"))) {
/* Make `bodylen` hold the length of the body */
String[] splitted = line.split("Content-Length:");
bodylen = Integer.parseInt(splitted[1].trim());
}
}
if (body == true) {
int charsRead;
char[] buffer = new char[1024];
while (bodylen > 0) {
charsRead = in.read(buffer);
if (charsRead == -1)
break;
bodylen -= charsRead;
tmp.append(buffer);
}
}
爲什麼會發生,以及如何解決它?
因爲它是用UTF-8編碼的,所以每個字節都被編碼爲一個「char」。我也用調試器檢查過它。 – 2012-01-19 00:48:20
此外,如果不是這種情況,那麼緩衝區讀數將會完全停止。 – 2012-01-19 00:50:19
Julian正確地注意到UTF-8字符可能需要多達6個字節。 – EricLaw 2012-01-19 01:44:42