简体   繁体   English

BufferedReader不读取第二个输出

[英]BufferedReader not reading second output

I am developing a client for a small game. 我正在为一个小型游戏开发客户。 Using sockets, I am parsing the request and responses with PrintWriter and BufferedReader classes. 使用套接字,我使用PrintWriterBufferedReader类解析请求和响应。

The issue I have is when BufferedReader is used for the second time (second response from server). 我遇到的问题是第二次使用BufferedReader时(服务器的第二次响应)。

Example: 例:

public class BotClient {

private final Socket socket;
private final PrintWriter writer;
private final BufferedReader reader;

public BotClient(final String gameId, final String botName) throws IOException {
    this.writer = new PrintWriter(socket.getOutputStream(), true);
    this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}

//Code that connects client to server. Works successfully.

public void sendGameRequest() {

try { 
    //This first is the FIRST request to server. This works SUCCESSFULLY.
    writer.println("GET " + "/playerInfo/?gameId=" + gameId + "&playerName=" + botName + " HTTP/1.0\r\n");

    reader.lines().forEach(System.out::println); // This will output game response successfully.

    //Now the problem occurs below here. I could do the same request but won't get an output.

    writer.println("GET " + "/playerInfo/?gameId=" + gameId + "&playerName=" + botName + " HTTP/1.0\r\n");

    reader.lines().forEach(System.out::println); //EMPTY PRINT

    // The above is EXACTLY the same request however this prints out nothing.

What could be the issue here and what is the best way to solve this problem? 这里可能是什么问题,什么是解决此问题的最佳方法?

Analysis 分析

I suppose that the second writer.println() method call is not going to happen, because the statement: 我想第二个writer.println()方法调用不会发生,因为该语句:

reader.lines().forEach(System.out::println);

describes reading the lines from the stream, while the end of the stream (ie when the socket is closed) is not reached. 描述了从流中读取行,而没有到达流的末尾(即关闭套接字时)。

As i see, it is a HTTP request: 如我所见,这是一个HTTP请求:

writer.println("GET " + "/playerInfo/?gameId=" + gameId + "&playerName=" + botName + " HTTP/1.0\\r\\n");

It could be that after the first request the connection was closed by remote pear. 可能是在第一个请求之后,远程梨关闭了连接。 So, each time that you send a request you should open the connections, send the request, wait and receive the response and close the socket. 因此,每次发送请求时,您都应该打开连接,发送请求,等待并接收响应并关闭套接字。

This is an extractor from the book: Http Definitive Guide by David Gourley and Brian Totty . 这是一本书的摘录David Gourley和Brian Totty撰写的Http Definitive Guide 在此处输入图片说明

Before send the second request check if the socket is open, if not, open it again and repeat the processes to send a request. 在发送第二个请求之前,请检查套接字是否打开,如果没有打开,请再次将其打开并重复发送请求的过程。

reader.lines() is just providing a streamed view that is equivalent to calling reader.readLine() repeatedly, until the end of the file is reached. reader.lines()仅提供一个流视图,该视图等效于重复调用reader.readLine() ,直到到达文件末尾。 Once you have read the entire stream, there are no more lines to read. 阅读完整个流后,就不再需要读取任何行。

You will need to store the lines. 您将需要存储行。 The easiest way to do this is to collect them into a List: 最简单的方法是将它们收集到一个列表中:

List<String> lines = reader.lines().collect(Collectors.toList());
lines.forEach(System.out::println);

A warning about InputStreamReader: Since you provided no charset, it will use the system's default charset. 关于InputStreamReader的警告:由于您未提供任何字符集,因此它将使用系统的默认字符集。 This means your code will run differently on Windows than it does on other operating systems; 这意味着您的代码在Windows上的运行方式将不同于其他操作系统。 a Windows machine probably will not be able to communicate with a non-Windows machine. Windows机器可能无法与非Windows机器通信。

To make it run identically on all systems, specify an explicit charset: 要使其在所有系统上相同地运行,请指定一个显式字符集:

    this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));

Documentation says 文件

The reader must not be operated on during the execution of the terminal stream operation. 在执行终端流操作期间,不得对阅读器进行操作。 Otherwise, the result of the terminal stream operation is undefined. 否则,终端流操作的结果是不确定的。 After execution of the terminal stream operation there are no guarantees that the reader will be at a specific position from which to read the next character or line. 在执行终端流操作之后,不能保证阅读器将处于从中读取下一个字符或行的特定位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM