我正在为小游戏开发客户端。使用套接字,我正在使用BufferedReader
和BufferedReader
类解析请求和响应。
我遇到的问题是第二次使用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.
时(服务器的第二次响应)。
示例:
"phd", "undergrad"
这可能是什么问题,解决这个问题的最佳方法是什么?
答案 0 :(得分:0)
我认为第二个writer.println()
方法调用不会发生,因为声明:
reader.lines().forEach(System.out::println);
描述了从流中读取行,而未到达流的末尾(即当套接字关闭时)。
答案 1 :(得分:0)
如我所见,这是一个HTTP请求:
writer.println("GET " + "/playerInfo/?gameId=" + gameId + "&playerName=" + botName + " HTTP/1.0\r\n");
可能是在第一次请求后,远程梨关闭了连接。因此,每次发送请求时,都应该打开连接,发送请求,等待并接收响应并关闭套接字。
这是本书中的一个提取器:David Gourley和Brian Totty的 Http权威指南。
在发送第二个请求之前检查套接字是否已打开,如果没有,请再次打开它并重复进程以发送请求。
答案 2 :(得分:0)
reader.lines()
只提供一个流式视图,相当于重复调用reader.readLine()
,直到到达文件末尾。一旦你读完整个流,就没有更多的行可供阅读。
您需要存储这些线条。最简单的方法是将它们收集到List中:
List<String> lines = reader.lines().collect(Collectors.toList());
lines.forEach(System.out::println);
关于InputStreamReader的警告:由于您没有提供字符集,它将使用系统的默认字符集。这意味着您的代码在Windows上的运行方式与在其他操作系统上的运行方式不同; Windows机器可能无法与非Windows机器通信。
要使其在所有系统上以相同方式运行,请指定显式字符集:
this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
答案 3 :(得分:0)
文档says
在执行终端流操作期间,不得操作阅读器。否则,终端流操作的结果是未定义的。执行终端流操作后,无法保证读者将处于读取下一个字符或行的特定位置。