我现在正在写一个http服务器,我在从套接字读取时遇到问题。
我的问题是来自客户端的inputStream
永远不会结束,并且一直在阅读,直到客户端关闭。
我知道客户端在发送http请求后不会立即关闭与服务器的连接。
当客户端发送了所有请求数据(即标题+正文)时,如何退出while loop
。
while (in.hasNextLine()) {
String line = in.nextLine();
if (line.equals("")){ // last line of request header is blank
break; // quit while loop when last line of header is reached
} else {
request = request + line + "\n";
}
}
在阅读了你们的评论和回答之后,这就是我想出来的,
is = incoming.getInputStream();
os = incoming.getOutputStream();
in = new Scanner(is);
out = new DataOutputStream(os);
RequestHandler rh = new RequestHandler();
int length = 0;
while (in.hasNextLine()) {
String line = in.nextLine();
if (line.equals("")) { // last line of request message
// header is a
// blank line
break; // quit while loop when last line of header is
// reached
}
if (line.startsWith("Content-Length: ")) { // get the
// content-length
int index = line.indexOf(':') + 1;
String len = line.substring(index).trim();
length = Integer.parseInt(len);
}
request = request + line + "\n";
}
byte[] body = new byte[length];
int i = 0;
while (i < length) {
byte b = in.nextByte();
body[i] = b;
i++;
}
但是,我仍然不知道按字节读取。我可以编写我的代码来读取-1,但是当没有EOF且客户端没有关闭连接时仍然卡住。
答案 0 :(得分:5)
根据您正在处理的请求,有三种方法可以检测流的结束:
GET
或HEAD
请求,您只需要读取HTTP标头,如果存在请求正文通常会被忽略,那么当您遇到\r\n\r\n
时,您就会触及请求的结尾(实际上是请求标头)。POST
方法,请阅读标题中的Content-Length
并阅读Content-Length
个字节。POST
方法并且Content-Length
标头不存在(最有可能发生),请先读取-1
,这是EOF
的信号}。答案 1 :(得分:3)
我知道了:)谢谢你们的评论和答案......
is = incoming.getInputStream(); // initiating inputStream
os = incoming.getOutputStream(); // initiating outputStream
in = new BufferedReader(new InputStreamReader(is)); // initiating
// bufferReader
out = new DataOutputStream(os); // initiating DataOutputSteream
RequestHandler rh = new RequestHandler(); // create a
// requestHandler
// object
String line;
while ((line = in.readLine()) != null) {
if (line.equals("")) { // last line of request message
// header is a
// blank line (\r\n\r\n)
break; // quit while loop when last line of header is
// reached
}
// checking line if it has information about Content-Length
// weather it has message body or not
if (line.startsWith("Content-Length: ")) { // get the
// content-length
int index = line.indexOf(':') + 1;
String len = line.substring(index).trim();
length = Integer.parseInt(len);
}
request.append(line + "\n"); // append the request
} // end of while to read headers
// if there is Message body, go in to this loop
if (length > 0) {
int read;
while ((read = in.read()) != -1) {
body.append((char) read);
if (body.length() == length)
break;
}
}
request.append(body); // adding the body to request
答案 2 :(得分:0)
我想分享一下效果很好的代码:
private static String getClientRequest(Socket client) throws IOException, SocketException {
System.out.println("Debug: got new client " + client.toString());
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));
StringBuilder requestBuilder = new StringBuilder();
String line;
int contectLegnth = 0;
while (!(line = br.readLine()).isBlank()) {
requestBuilder.append(line + "\r\n");
if (line.toLowerCase().startsWith("content-length")) {
contectLegnth = Integer.parseInt(line.split(":")[1].trim());
}
}
StringBuilder requestBodyBuilder = new StringBuilder();
if (contectLegnth > 0) {
int read;
while ((read = br.read()) != -1) {
requestBodyBuilder.append((char) read);
if (requestBodyBuilder.length() == contectLegnth)
break;
}
requestBuilder.append("\r\n" + requestBodyBuilder);
}
return requestBuilder.toString();
}