Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java写入关闭的输出流未引发ioexception_Java_Sockets_Outputstream - Fatal编程技术网

Java写入关闭的输出流未引发ioexception

Java写入关闭的输出流未引发ioexception,java,sockets,outputstream,Java,Sockets,Outputstream,下面是我的客户机/服务器的流程 套接字是在主线程中创建的 套接字传递到线程1 客户端向服务器发送数据 服务器响应客户端 服务器通过调用close() 套接字返回到主线程,然后传递到线程2 客户端将数据写入服务器-无异常、无错误,服务器不获取数据 客户端尝试读取数据-无异常,无错误 如何检测插座已关闭的问题 try { os = new DataOutputStream(this.socket.getOutputStream()); os.write(data);

下面是我的客户机/服务器的流程

套接字是在主线程中创建的

  • 套接字传递到线程1
  • 客户端向服务器发送数据
  • 服务器响应客户端
  • 服务器通过调用
    close()
  • 套接字返回到主线程,然后传递到线程2
  • 客户端将数据写入服务器-无异常、无错误,服务器不获取数据
  • 客户端尝试读取数据-无异常,无错误
  • 如何检测插座已关闭的问题

    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();
        }
    
    永远不会抛出异常。它说
    写了60个字节
    。有什么想法吗


    更新

    以下是我阅读回复的方式。我等待数据,读取前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;
        }
    
    is=newdataInputStream(this.socket.getInputStream());
    while(true){
    while(is.available()>0){
    bos.write(is.read());
    }
    如果(contentLength==0&&bos.size()>3){
    byte[]bytes=bos.toByteArray();
    byte[]size=Arrays.copyOf(字节,4);
    contentLength=ByteBuffer.wrap(size.getInt();
    }
    if(bos.size()-4
    它说它写了60个字节,因为它写了。服务器只是不再侦听。您需要获取输入流以查看是否存在任何内容。如果什么都没有恢复,那么你就知道连接不起作用了

    更新

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

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

    这样,如果花费的时间超过x秒,它将超时,您可以在while循环后执行一些错误捕获

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

    您的问题是在此处检测输入的结尾:

        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
    

    好的,我明白了。我将用我读取数据的方法更新我的问题,这可能是罪魁祸首。你检查过SocketException吗?如果你正在关闭所有东西,那么它也应该抛出它。是的,不会抛出异常。我更新了这个问题,补充了关于threadsHow之间传递的套接字的信息。你能在不阻塞的情况下从封闭流中读取多少字节?没有一个因此,
    available()
    必须返回零。您没有写入到关闭的输出流。您正在向可能已被对等方关闭的连接进行写入。这不是一回事。