Java写入关闭的输出流而不是抛出ioexception

时间:2016-07-22 19:09:30

标签: java sockets outputstream

这是我的客户端/服务器的流程。

在主线程中创建套接字。

  1. 套接字传递给线程1。
  2. 客户端将数据发送到服务器
  3. 服务器响应客户端
  4. 服务器通过调用close()
  5. 来关闭输入流,输出流和套接字
  6. 套接字返回主线程,然后传递给线程2。
  7. 客户端将数据写入服务器 - 没有异常,没有错误,服务器没有数据
  8. 客户端尝试读取数据 - 没有例外,没有错误
  9. 如何检测套接字已关闭的问题?

    try {
            os = new DataOutputStream(this.socket.getOutputStream());
            os.write(data);
            os.flush();
            System.out.println("Written " + data.length + " bytes");
        } catch (IOException e) {
            System.out.println("Client failed to write to stream");
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    

    永远不会抛出异常。它说Written 60 bytes。有什么想法吗?

    更新

    以下是我阅读回复的方式。我等待数据,读取前4个字节(给出响应的长度),并继续读取,直到我读取指定的长度。这个循环永远不会结束,因为没有数据进入。

    is = new DataInputStream(this.socket.getInputStream());
        while(true){
            while(is.available() > 0){
                bos.write(is.read());
            }
            if(contentLength == 0 && bos.size() > 3){
                byte[] bytes = bos.toByteArray();
                byte[] size = Arrays.copyOf(bytes, 4);
                contentLength = ByteBuffer.wrap(size).getInt();
            }
            if(bos.size() - 4 < contentLength){
                continue;
            }
            break;
        }
    

2 个答案:

答案 0 :(得分:1)

它说它写了60个字节,因为它确实如此。服务器不再是在听。您需要获取输入流以查看是否存在任何内容。如果什么都没有回来,那么你知道这种联系并不奏效。

更新

使用计时器确定服务器是否正在响应。

Long currenttime = System.currentTimeMillis();
while(System.currentTimeMillis() - currentTime < x){ //x = miliseconds you want to wait
    (try to read from server)
}

这种方式如果花费的时间超过x秒,它会超时,你可以在while循环后执行一些错误捕获

答案 1 :(得分:1)

当服务器关闭其TCP连接的末尾时,它会发送一个FIN数据包来告诉客户端。客户端程序将此视为到达结尾的InputStream。此外,如果客户端尝试写入服务器将发送RST数据包以发出错误信号。如果客户端程序在收到RST后尝试写入,则API将抛出一个SocketException,并显示消息&#34; connection reset。&#34;

你的问题是在这里检测到输入结束:

    while(is.available() > 0){
        bos.write(is.read());
    }

available方法可能不会按照您的想法执行操作。如果要读取4个字节,请读取4个字节:

byte[] bytes = new byte[4];
is.readFully(bytes); // throws EOFException on end of input