我正在开发一个分布式系统,它通过Socket接收请求,并使用OutputStream将结果写回来。
我遇到了问题,因为我必须返回一个非常大的字符串,但Java只是在我调用方法print()之后保持代码的执行而不完成打印:
public void attendRequisition(Socket clientSocket) {
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream());
pw.print(getResults());
pw.close()
}
一些信息:
我相信这种情况正在发生,因为Java认为方法print()已完成执行,但可能发生的是Java将消息发送到JVM,JVM将其发送到网络适配器,并且因为消息非常大,在网络适配器能够发送整个消息之前调用close()方法。
我需要的是确保Java只在打印过程完成并且客户端收到整个消息后才运行指令close()的方法。
更新:通过添加Thread.sleep()
,我能够正常运行。通过这样做,SO有足够的时间在Java关闭连接之前发送消息。但我不想使用这个解决方案,它涉及太多问题。
答案 0 :(得分:0)
我能够使用DataOutputStream.writeBytes()
解决问题。这样,执行仅在方法完成发送数据时继续。它比较慢,但有效。
答案 1 :(得分:-1)
我敢打赌,如果你使用另一个构造函数(即第二个参数是布尔值来表示你想要刷新的那个)那么你的例子就可以了。你构建对象的方式是autoflush被禁用。
如果您的真实代码更复杂,那么您可以在适当的时刻调用pw.flush()。
答案 2 :(得分:-1)
由于Java运行close()指令,我可以看到消息即将被删除
不,你不能。你可以看到被删除的信息,除非你对它有多长时间存在错误,但你会对原因做出结论。 Java在完成发送之前不会关闭PrintWriter
。它将编写器刷新到套接字发送缓冲区,必要时阻塞,然后关闭底层套接字,后者在数据后面缓冲FIN。在FIN到达之前,所有数据都被发送,并且所有数据都被接收,这将信号流结束到接收器。
可能您不知道PrintWriter
吞下异常,因此不应该通过网络使用。