我的客户端代码如下:
Socket s = new Socket(server.getHostName(), server.getPort());
PrintWriter p = new PrintWriter(s.getOutputStream());
p.println(message);
p.flush();
s.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String newLine;
StringBuffer response = new StringBuffer();
while((newLine = br.readLine()) != null)
response.append(newLine);
System.out.println(response.toString());
p.close();
br.close();
和服务器代码如下:
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String nextLine;
StringBuffer request = new StringBuffer();
System.out.println("Starting read....");
String nextline;
while((nextline = br.readLine()) != null){
System.out.println(nextline);
request.append(nextline);
}
System.out.println("Message recived!!");
System.out.println("Request: " + request);
PrintWriter p = new PrintWriter(s.getOutputStream());
p.println("Hello, fileclient!");
System.out.println("Message sent!!");
p.close();
br.close();
在我放行s.shutDownInput()
之前,服务器代码会挂起br.readLine().
我设法修复的方法是关闭PrintWriter
一些方法,通过p.close()
或者通过目前没有的方式
关闭套接字就像关闭PrintWriter
到p.close()
一样。之后,客户端和服务器之间的交互是完美的。
为什么PrintWriter
或BufferedReader
在PrintWriter
以某种方式关闭之前不会发送/接收?
答案 0 :(得分:1)
它与PrintWriter
没有任何关系。这是您的应用程序协议错误。
服务器循环读取行直到流结束。
客户端正在发送一行,然后没有关闭套接字,因此没有发送流末尾(直到您添加了关闭)。
服务器正在响应。
然后客户正在阅读。
因此,在服务器退出循环之前,客户端不会读取任何内容,并且服务器没有退出循环,因为客户端正在读取未关闭。
所以下定决心。可能服务器应该只读一行。
答案 1 :(得分:1)
双方的行为完全按照你的要求去做。特别是,在指派任何响应之前,您将指示服务器专门读取客户端发送的所有内容:
String nextline;
while((nextline = br.readLine()) != null){
System.out.println(nextline);
request.append(nextline);
}
重要的是要理解,在 stream 的错误或结束之前不会停止读取,其中套接字上的流结束对应于已关闭的另一端并且已读取所有数据。换句话说,在分派响应之前,您的服务器会等待整个会话的结束,而不是单个消息的结束。
由于这显然不是您想要的,因此您需要在服务器上实施不同的策略,以确定何时处理到目前为止收到的数据并发送响应。如果您确信自己的邮件不会包含内部换行符,那么这可能就像服务器在发送每个回复之前只执行一个 br.readLine()
一样简单。