有没有办法知道BufferedOutputStream线程的flush()方法何时或是否成功完成?就我而言,我用它来通过java.net.Socket发送一个简单的字符串。在下面的代码中,flush()方法与BufferedReader.read()方法并行运行,并且输入读取立即阻止套接字输出,从而产生类似于死锁的内容。我想做的是等待输出结束,然后开始读取输入。
Socket sk = new Socket("192.168.0.112", 3000);
BufferedOutputStream bo = new BufferedOutputStream(sk.getOutputStream());
bo.write(message.getBytes());
bo.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
String line = br.readLine();
if (line.equals("ack")) {
System.out.println("ack");
}
sk.close();
更新
的ServerSocket:
ServerSocket ss = new ServerSocket(3000);
System.out.println("server socket open");
while (true) {
Socket sk = ss.accept();
System.out.println("new connection");
BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream()));
String line = br.readLine();
System.out.println("received line: " + line);
BufferedOutputStream bo = new BufferedOutputStream(sk.getOutputStream());
bo.write("ack".getBytes()); bo.flush();
sk.close();
}
更新:
@Global Variable - 读取阻塞套接字的原因是它正在等待\ n,确实。使用
bo.write("ack\n".getBytes());
而不是
bo.write("ack".getBytes());
让它发挥作用。
关于最初的问题,有没有办法知道flush()方法是否成功完成,@ Stephen C提供了答案:
没有办法知道基于Socket或OutputStream API。 获得这种保证的正常方法是使用遥控器 应用程序发送"回复"作为回应,并在当地阅读 侧。
这"回复"在代码示例中实现,它可以工作。
答案 0 :(得分:2)
有没有办法知道
flush()
线程的BufferedOutputStream
方法何时或是否成功完成?
这取决于“成功完成”的含义。
flush()
方法确保管道中的所有未发送数据都已推送到操作系统网络堆栈。完成后,您可以说flush()
已成功完成。您知道发生这种情况的方式是flush()
调用返回。
另一方面,如果您希望确保数据已经(全部)已经传送到远程计算机,或者远程应用程序已经读取了它(全部)......根本没有办法知道Socket或OutputStream API。获得这种保证的正常方法是让远程应用程序发送“回复”作为响应,并在本地读取它。
在下面的代码中,flush()方法与BufferedReader.read()方法并行运行,并且输入读取会立即阻塞套接字输出,从而产生类似于死锁的内容。
您所谈论的代码基本上是正确的方法。等待响应的方法就是这样读。
如果它不起作用,那么您需要比较客户端和服务器端正在做什么:
服务器是否在等待客户端发送更多内容?也许是行结束序列?
服务器是否发送了响应?
是否flush()
回复?
客户端和服务器正在做什么可以导致表单或死锁,但解决方案是解决不匹配问题。等待flush()
的某种假设性确认不是答案。
<强>更新强>
问题确实是不匹配的。例如,服务器写入"ack"
,但客户端期望"ack\n"
。在客户端也是如此 - &gt;服务器案例......除非message
始终以换行符结尾。
答案 1 :(得分:0)
您的代码正在阅读reader.readLine()
。写作时你的写作是什么?您可能希望将\ n附加到您正在编写的字符串中。
答案 2 :(得分:0)
我试图重现你的问题。首先,我也遇到了某种阻塞状态,直到我意识到,我在服务器端也使用了readLine
。但是我发送的消息没有得出结论\n
。因此,serversocket仍然在InputStream
等待,而没有通过ACK
向客户端发送OutputStream
。我认为,@Global Variable
是对的。