Java BufferedReader.ready()的行为差异
我正在尝试使用套接字模拟一个简单的HTTP服务器和一个客户端。 BufferedReader用于逐行读取请求。 为了标识套接字输入流的结尾,使用了BufferedReader的ready()方法 Java文档准备就绪:Java BufferedReader.ready()的行为差异,java,sockets,inputstream,java-io,Java,Sockets,Inputstream,Java Io,我正在尝试使用套接字模拟一个简单的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
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应用程序中尝试它时,会不断返回true。BufferedReader准备返回false的Java程序中是否需要包含任何内容
服务器:
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.server;
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入java.net.ServerSocket;
导入java.net.Socket;
公共类HttpWebServer{
私有静态最终字符串ROOT_URL=“/”;
私有静态最终字符串FAV_ICON_URL=“/favicon.ico”;
私有静态最终字符串GET_METHOD=“GET”;
私有静态最终字符串POST_METHOD=“POST”;
公共静态void main(字符串[]args)引发IOException{
ServerSocket ServerSocket=新的ServerSocket(8081);
System.out.println(“已建立的连接……”
+serverSocket.getLocalSocketAddress());
套接字clientSocket=null;
while(true){
clientSocket=serverSocket.accept();
新建HttpWebServer().HandlerRequest(clientSocket);
}
}
私有void handleRequest(套接字clientSocket)引发IOException{
System.out.println(“收到一个http请求,数据如下”);
InputStream socketInputStream=clientSocket.getInputStream();
BufferedReader br=新的BufferedReader(新的InputStreamReader(
socketInputStream);
字符串行=null;
字符串url=null;
字符串方法=null;
StringBuilder isStringBuilder=新StringBuilder();
而((line=br.readLine())!=null){
isStringBuilder.append(行).append(“\r\n”);
如果(url==null&&!line.isEmpty()){
方法=行分割(“\\”[0];
url=line.split(“\\”[1];
}
如果(!br.ready())
打破
}
System.out.println(isStringBuilder.toString());
if(url!=null&&(method!=null)&&method.trim().equals(GET_method)){
if(url.trim().equals(ROOT_url))
HandleGetRotRequest(客户端插座);
else if(url.trim().equalsIgnoreCase(FAV_图标_url))
HandlegicationRequest(客户端套接字);
}
/*
*字节[]字节=新字节[1024];
*
*整数计数=0;
*
*do{count=socketInputStream.read(字节);字符串输出=new
*字符串(字节,0,计数);系统输出打印(输出);
*System.out.flush();
*
*//count=socketInputStream.read(字节);System.out.println(计数);
*
*}while(socketInputStream.available()>0);
*/
System.out.println(“已完成的处理请求”);
}
私有无效HandlegictionRequest(套接字客户端套接字){
System.out.println(“尚未实现!!”;
}
私有void HandleGetRotRequest(套接字客户端套接字)引发IOException{
OutputStream clientOS=clientSocket.getOutputStream();
StringBuilder sb=新的StringBuilder();
sb.append(“HTTP/1.1200确定”).append(“\r\n”).append(“\r\n”)
.append(“”)。append(“成功”)。append(“”);
字符串响应=sb.toString();
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();
}
}
package com.test.http.client;
导入java.io.BufferedReader;
导入java.io.BufferedWriter;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入java.io.OutputStreamWriter;
导入java.net.Socket;
导入java.net.UnknownHostException;
公共类HttpSimpleClient{
公共静态void main(字符串[]args)抛出UnknownHostException、IOException{
套接字=新套接字(“本地主机”,8081);
StringBuilder requestBuilder=新建StringBuilder();
append(“GET”)
.append(“/”).append(“HTTP/1.1”).append(“\r\n”)
.append(“连接:保持活动”).append(“\r\n”).append(“\r\n”)
.附加(“某人”);
OutputStream socketOutputStream=socket.getOutputStream();
BufferedWriter bw=新的BufferedWriter(新的OutputStreamWriter(socketOutputStream));
write(requestBuilder.toString());
bw.flush();
System.out.println(“发送:+requestBuilder.toString());
BufferedReader br=新的BufferedReader(新的InputStreamReader(
getInputStream());
StringBuilder responseBuilder=新建StringBuilder();
字符串行=null;
而((line=br.readLine())!=null){
responseBuilder.append(行);
如果(!br.ready()){
打破
}
}
System.out.println(“响应:+requestBuilder.toString());
socket.close();
}
}
在
bw.flush()之后关闭bw代码>在读取inputstream时出错,关闭套接字本身。您应该读取到请求头的末尾。这是“\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;
}
如果要读取请求正文某些正文
。您必须将Content Length:Length\u OF_BODY
添加到请求头中。服务器解析它,然后读取正文的长度字节。在这种情况下,您不能使用BufferedReader
您应该读取到请求头的末尾。这是“\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;
}
如果要读取请求正文某些正文
。您必须将Content Length:Length\u OF_BODY
添加到请求头中。和s