gpt4 book ai didi

java - BufferedReader.ready() 行为的差异

转载 作者:行者123 更新时间:2023-12-02 02:42:52 26 4
gpt4 key购买 nike

我正在尝试使用套接字模拟一个简单的 HTTP 服务器和客户端。BufferedReader 用于逐行读取请求。为了识别套接字输入流的结束,使用 BufferedReader 的 read() 方法。

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 应用程序尝试它时,它不断返回 true。我是否需要在 Java 程序中包含任何内容才能使 BufferedReader 准备好返回 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()之后关闭bw;通过在读取输入流时出错来关闭Socket本身。

最佳答案

您应该读到请求 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;
}

如果你想读取请求正文Some body。您必须将 Content-Length: LENGTH_OF_BODY 添加到请求 header 。服务器解析它,然后读取LENGTH_OF_BODY字节。在这种情况下,您不能使用 BufferedReader

关于java - BufferedReader.ready() 行为的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45125800/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com