BufferedReader.ready() 的行为差异
Difference in the behaviour of BufferedReader.ready()
我正在尝试模拟一个简单的 HTTP 服务器和一个使用套接字的客户端。
BufferedReader 用于逐行读取请求。
为了识别套接字输入流的结尾,使用了 BufferedReader 的 ready() 方法。
Java 待办文件:
Returns:
True if the next read() is guaranteed not to block for
input, false otherwise. Note that returning false does not
guarantee that the next read will block.
当我从浏览器访问服务器时,这工作正常。但是当我从 java 应用程序中尝试它时,它一直保持 returning 为真。我是否需要在 Java 程序中包含任何内容以使 BufferedReader 准备好 return false?
服务器:
package com.test.http.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class HttpWebServer {
private static final String ROOT_URL = "/";
private static final String FAV_ICON_URL = "/favicon.ico";
private static final String GET_METHOD = "GET";
private static final String POST_METHOD = "POST";
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8081);
System.out.println("Established connection........."
+ serverSocket.getLocalSocketAddress());
Socket clientSocket = null;
while (true) {
clientSocket = serverSocket.accept();
new HttpWebServer().handleRequest(clientSocket);
}
}
private void handleRequest(Socket clientSocket) throws IOException {
System.out.println("Received a http request with data as follows");
InputStream socketInputStream = clientSocket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(
socketInputStream));
String line = null;
String url = null;
String method = null;
StringBuilder isStringBuilder = new StringBuilder();
while ((line = br.readLine()) != null) {
isStringBuilder.append(line).append("\r\n");
if (url == null && !line.isEmpty()) {
method = line.split("\ ")[0];
url = line.split("\ ")[1];
}
if (!br.ready())
break;
}
System.out.println(isStringBuilder.toString());
if (url != null && (method != null) && method.trim().equals(GET_METHOD)) {
if (url.trim().equals(ROOT_URL))
handleGetRootRequest(clientSocket);
else if (url.trim().equalsIgnoreCase(FAV_ICON_URL))
handleGetIconRequest(clientSocket);
}
/*
* byte[] bytes = new byte[1024];
*
* int count = 0;
*
* do{ count = socketInputStream.read(bytes); String output = new
* String(bytes, 0, count); System.out.print(output);
* System.out.flush();
*
* //count = socketInputStream.read(bytes); System.out.println(count);
*
* }while(socketInputStream.available() > 0);
*/
System.out.println("Completed processing request");
}
private void handleGetIconRequest(Socket clientSocket) {
System.out.println("Yet to implement !!");
}
private void handleGetRootRequest(Socket clientSocket) throws IOException {
OutputStream clientOS = clientSocket.getOutputStream();
StringBuilder sb = new StringBuilder();
sb.append("HTTP/1.1 200 OK ").append("\r\n").append("\r\n")
.append("<TITLE>").append("SUCCESS").append("</TITLE>");
String response = sb.toString();
clientOS.write(response.getBytes("UTF-8"));
clientOS.flush();
clientOS.close();
clientSocket.close();
}
}
客户:
package com.test.http.client;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class HttpSimpleClient {
public static void main(String[] args) throws UnknownHostException, IOException{
Socket socket = new Socket("localhost",8081);
StringBuilder requestBuilder = new StringBuilder();
requestBuilder.append("GET")
.append(" / ").append("HTTP/1.1").append("\r\n")
.append("Connection: keep-alive").append("\r\n").append("\r\n")
.append(" Some Body");
OutputStream socketOutputStream = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socketOutputStream));
bw.write(requestBuilder.toString());
bw.flush();
System.out.println("<Client> Send:"+ requestBuilder.toString());
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
StringBuilder responseBuilder = new StringBuilder();
String line = null;
while((line = br.readLine()) != null){
responseBuilder.append(line);
if(!br.ready()){
break;
}
}
System.out.println(" Response: "+requestBuilder.toString());
socket.close();
}
}
在 bw.flush();
通过读取输入流时出错关闭 Socket 本身后关闭 bw。
您应该阅读到请求 header 的末尾。即"\r\n\r\n"
序列。
while ((line = br.readLine()) != null) {
isStringBuilder.append(line).append("\r\n");
if (url == null && !line.isEmpty()) {
method = line.split("\ ")[0];
url = line.split("\ ")[1];
}
if (line.isEmpty())
break;
}
如果您想阅读请求body Some body
。您必须将 Content-Length: LENGTH_OF_BODY
添加到请求 header。服务器解析它,然后读取 LENGTH_OF_BODY
bytes。在这种情况下,您不能使用 BufferedReader
.
我正在尝试模拟一个简单的 HTTP 服务器和一个使用套接字的客户端。 BufferedReader 用于逐行读取请求。 为了识别套接字输入流的结尾,使用了 BufferedReader 的 ready() 方法。
Java 待办文件:
Returns:
True if the next read() is guaranteed not to block for
input, false otherwise. Note that returning false does not
guarantee that the next read will block.
当我从浏览器访问服务器时,这工作正常。但是当我从 java 应用程序中尝试它时,它一直保持 returning 为真。我是否需要在 Java 程序中包含任何内容以使 BufferedReader 准备好 return false?
服务器:
package com.test.http.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class HttpWebServer {
private static final String ROOT_URL = "/";
private static final String FAV_ICON_URL = "/favicon.ico";
private static final String GET_METHOD = "GET";
private static final String POST_METHOD = "POST";
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8081);
System.out.println("Established connection........."
+ serverSocket.getLocalSocketAddress());
Socket clientSocket = null;
while (true) {
clientSocket = serverSocket.accept();
new HttpWebServer().handleRequest(clientSocket);
}
}
private void handleRequest(Socket clientSocket) throws IOException {
System.out.println("Received a http request with data as follows");
InputStream socketInputStream = clientSocket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(
socketInputStream));
String line = null;
String url = null;
String method = null;
StringBuilder isStringBuilder = new StringBuilder();
while ((line = br.readLine()) != null) {
isStringBuilder.append(line).append("\r\n");
if (url == null && !line.isEmpty()) {
method = line.split("\ ")[0];
url = line.split("\ ")[1];
}
if (!br.ready())
break;
}
System.out.println(isStringBuilder.toString());
if (url != null && (method != null) && method.trim().equals(GET_METHOD)) {
if (url.trim().equals(ROOT_URL))
handleGetRootRequest(clientSocket);
else if (url.trim().equalsIgnoreCase(FAV_ICON_URL))
handleGetIconRequest(clientSocket);
}
/*
* byte[] bytes = new byte[1024];
*
* int count = 0;
*
* do{ count = socketInputStream.read(bytes); String output = new
* String(bytes, 0, count); System.out.print(output);
* System.out.flush();
*
* //count = socketInputStream.read(bytes); System.out.println(count);
*
* }while(socketInputStream.available() > 0);
*/
System.out.println("Completed processing request");
}
private void handleGetIconRequest(Socket clientSocket) {
System.out.println("Yet to implement !!");
}
private void handleGetRootRequest(Socket clientSocket) throws IOException {
OutputStream clientOS = clientSocket.getOutputStream();
StringBuilder sb = new StringBuilder();
sb.append("HTTP/1.1 200 OK ").append("\r\n").append("\r\n")
.append("<TITLE>").append("SUCCESS").append("</TITLE>");
String response = sb.toString();
clientOS.write(response.getBytes("UTF-8"));
clientOS.flush();
clientOS.close();
clientSocket.close();
}
}
客户:
package com.test.http.client;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class HttpSimpleClient {
public static void main(String[] args) throws UnknownHostException, IOException{
Socket socket = new Socket("localhost",8081);
StringBuilder requestBuilder = new StringBuilder();
requestBuilder.append("GET")
.append(" / ").append("HTTP/1.1").append("\r\n")
.append("Connection: keep-alive").append("\r\n").append("\r\n")
.append(" Some Body");
OutputStream socketOutputStream = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socketOutputStream));
bw.write(requestBuilder.toString());
bw.flush();
System.out.println("<Client> Send:"+ requestBuilder.toString());
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
StringBuilder responseBuilder = new StringBuilder();
String line = null;
while((line = br.readLine()) != null){
responseBuilder.append(line);
if(!br.ready()){
break;
}
}
System.out.println(" Response: "+requestBuilder.toString());
socket.close();
}
}
在 bw.flush();
通过读取输入流时出错关闭 Socket 本身后关闭 bw。
您应该阅读到请求 header 的末尾。即"\r\n\r\n"
序列。
while ((line = br.readLine()) != null) {
isStringBuilder.append(line).append("\r\n");
if (url == null && !line.isEmpty()) {
method = line.split("\ ")[0];
url = line.split("\ ")[1];
}
if (line.isEmpty())
break;
}
如果您想阅读请求body Some body
。您必须将 Content-Length: LENGTH_OF_BODY
添加到请求 header。服务器解析它,然后读取 LENGTH_OF_BODY
bytes。在这种情况下,您不能使用 BufferedReader
.