Java 插座';s PrintWriter没有';在关闭之前不要发送
我的客户端代码如下所示:Java 插座';s PrintWriter没有';在关闭之前不要发送,java,sockets,networking,Java,Sockets,Networking,我的客户端代码如下所示: 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.getIn
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();
和服务器代码,如下所示:
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()。
我设法解决的方法是通过p.close()
或通过当前不可用的方式关闭PrintWriter
关闭套接字,就像通过p关闭PrintWriter
一样。关闭()
。之后,客户端和服务器之间的交互就完美了
为什么
PrintWriter
或BufferedReader
在PrintWriter
关闭之前不发送/接收?它与PrintWriter
没有任何关系。这是您的应用程序协议错误
- 服务器正在循环读取行,直到流结束
- 客户端正在发送一行数据,但没有关闭套接字,因此没有发送流的结尾(直到您添加关机)
- 然后服务器会做出响应
- 客户正在阅读
所以下定决心吧。可能服务器应该只读取一行。它与
PrintWriter
没有任何关系。这是您的应用程序协议错误
- 服务器正在循环读取行,直到流结束
- 客户端正在发送一行数据,但没有关闭套接字,因此没有发送流的结尾(直到您添加关机)
- 然后服务器会做出响应
- 客户正在阅读
所以下定决心吧。可能服务器应该只读取一行。双方的行为都与您告诉他们的完全一致。特别是,您特别指示服务器在发送任何响应之前读取客户端发送的所有内容:
String nextline;
while((nextline = br.readLine()) != null){
System.out.println(nextline);
request.append(nextline);
}
重要的是要理解,直到出现错误或流结束时才会停止读取,其中套接字上的流结束对应于另一端已关闭且所有数据已读取。换句话说,您的服务器等待整个会话结束,而不是单个消息结束,然后再发送响应
因为这显然不是您想要的,所以您需要在服务器上实现不同的策略,以确定何时处理到目前为止接收到的数据并发送响应。如果您确信您的消息不会包含内部换行符,那么这可能很简单,因为服务器在发送每个响应之前只执行一个
br.readLine()
。双方的行为与您告诉他们的完全一样。特别是,您特别指示服务器在发送任何响应之前读取客户端发送的所有内容:
String nextline;
while((nextline = br.readLine()) != null){
System.out.println(nextline);
request.append(nextline);
}
重要的是要理解,直到出现错误或流结束时才会停止读取,其中套接字上的流结束对应于另一端已关闭且所有数据已读取。换句话说,您的服务器等待整个会话结束,而不是单个消息结束,然后再发送响应
因为这显然不是您想要的,所以您需要在服务器上实现不同的策略,以确定何时处理到目前为止接收到的数据并发送响应。如果您确信您的邮件不会包含内部换行符,那么这可能很简单,因为服务器在发送每个响应之前只执行一个?缓冲是正常的,关闭流会迫使它刷新其内容。我猜他希望保持套接字打开,以便能够发送更多数据。正如现在的一个注意事项,您应该使用try with resources自动正确地关闭资源,如
socket
s。它看起来是这样的:try(sockets=newsocket(…){your code}
。Java现在在到达末尾时自动关闭try(…)
部分中定义的所有资源(关闭}
)。这可以通过实现AutoCloseable
的所有类来实现:@Zabuza谢谢,我提供了与问题相关的代码。在实际的程序中,我使用了try-with-resources。你为什么期望它这样做?缓冲是正常的,关闭流会迫使它刷新其内容。我猜他希望保持套接字打开,以便能够发送更多数据。正如现在的一个注意事项,您应该使用try with resources自动正确地关闭资源,如socket
s。它看起来是这样的:try(sockets=newsocket(…){your code}
。Java现在在到达末尾时自动关闭try(…)
部分中定义的所有资源(关闭}
)。这可以通过实现AutoCloseable
的所有类来实现:@Zabuza谢谢,我提供了与问题相关的代码。在实际的程序中,我使用了try-with-resources。您和@John Bollinger都是正确的。我不知道br.readLine()一直读到流的末尾。我以为它一直持续到没有更多的台词可读为止。非常感谢你!对于未来的人,阅读直到br.readLine()等于null,或者如果它接收到并使用单个“q”。将记录readLine()
的行为。它直到流结束时才读取,但您的代码会这样做,通过循环直到返回null,这是在流结束时执行的。您和@John Bollinger都是正确的。我不知道br.readLine()是