Java 当从套接字读取时,如何检测客户端何时完成发送请求?
我现在正在编写http服务器,从套接字读取时遇到问题。 我的问题是,来自客户端的Java 当从套接字读取时,如何检测客户端何时完成发送请求?,java,sockets,httprequest,httpserver,Java,Sockets,Httprequest,Httpserver,我现在正在编写http服务器,从套接字读取时遇到问题。 我的问题是,来自客户端的inputStream永远不会结束,它会一直读取,直到客户端关闭。 我知道客户端在发送http请求后不会立即关闭与服务器的连接。 当客户端发送了所有请求数据(即标题+正文)时,如何退出while循环 while (in.hasNextLine()) { String line = in.nextLine(); if (line.equals("")){ // last line of request
inputStream
永远不会结束,它会一直读取,直到客户端关闭。
我知道客户端在发送http请求后不会立即关闭与服务器的连接。
当客户端发送了所有请求数据(即标题+正文)时,如何退出while循环
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";
}
}
在阅读了你们的评论和回答之后,这就是我想到的
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++;
}
is=incoming.getInputStream();
os=传入的.getOutputStream();
in=新扫描仪(is);
out=新数据输出流(os);
RequestHandler rh=新的RequestHandler();
整数长度=0;
while(在.hasNextLine()中){
String line=in.nextLine();
if(line.equals(“”){//请求消息的最后一行
//标题是一个
//空行
break;//在返回头的最后一行时退出while循环
//达到
}
if(line.startsWith(“Content-Length:”){//获取
//内容长度
int index=line.indexOf(':')+1;
字符串len=line.substring(index.trim();
长度=整数.parseInt(len);
}
请求=请求+行+“\n”;
}
字节[]正文=新字节[长度];
int i=0;
while(i
但是,我仍然不理解字节读取。我可以编写代码直到-1,但在没有EOF且客户端未关闭连接时仍会被卡住。根据您正在处理的请求,有3种检测流结束的方法:
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";
}
}
GET
或HEAD
请求,您只需要读取HTTP头,请求体通常会被忽略(如果它存在),因此当您遇到\r\n\r\n
时,您会到达请求的末尾(实际上是请求头)POST
方法,请读取标题中的Content Length
,并最多读取Content Length
字节POST
方法,并且内容长度
标题不存在(这很可能发生),则读取直到返回-1
,这是EOF
的信号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(); // 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
我想与大家分享我的代码:
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";
}
}
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();
}
如果它是
GET
,则可以在获取\r\n\r\n
后停止,如果它有请求正文,则可以在从请求正文读取内容长度
字节后停止。Scanner.nextByte()根据当前基数进行解析;它不返回原始字节。您应该为此使用DataInputStream
。是的,我知道它的readLine()
方法已被弃用。对于所有方法,包括GET、HEAD、PUT、POST、DELETE等,省略(1)并仅使用(2)和(3)。。。如果客户端正在执行keepalive,则您必须读取所有请求的末尾,否则您将无法正确获取下一个请求。您好,@EJP,感谢您提及keepalive
。如果内容长度
不存在,如果客户端正在执行保留活动
,如何检测请求的结束?这不是法律情况。如你在(3)中所述,如果客户需要保持活动状态,他必须发送一个内容长度。大多数非GET
/HEAD
请求可以有一个消息正文,因此将#2和#3限制为POST
是错误的。此外,“如果客户端正在执行保持活动状态,则必须发送内容长度”也不是真的。如果改为使用传输编码:分块
或内容类型:多部分/..
,则内容长度
是可选的。而读取直到EOF
对请求无效,仅对响应有效。请参阅,以了解在所有场景中检测消息结束时需要遵循的确切规则,无论是否使用keep alive。