java.net.Socket> outputStream> BufferedOutputStream flush()确认

时间:2015-03-09 13:08:28

标签: java sockets tcp

有没有办法知道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。   获得这种保证的正常方法是使用遥控器   应用程序发送"回复"作为回应,并在当地阅读   侧。

这"回复"在代码示例中实现,它可以工作。

3 个答案:

答案 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是对的。