0

我正在创建一个服务器以接收来自客户端的文本和二进制数据。它与文本数据以及第一次接收二进制文件一起工作,但在此之后它不会继续读取数据并抛出异常。 这里是我的服务器代码:为什么在读取二进制文件后DataInputStream不会继续接收数据

public class ConnectedProcessThread implements Runnable{ 
    private final Socket socket; 

    public ConnectedProcessThread(Socket clientSocket){ 
     socket = clientSocket; 
    } 

    public void run(){ 
     DataInputStream dis = null; 
     try{ 
      while(true) { 
       dis = new DataInputStream(socket.getInputStream()); 
       String meta = dis.readUTF(); 
       Log.i("Data received", meta); 
       if(meta.equalsIgnoreCase("Text")){ 
        String message = dis.readUTF(); 
        Log.i("Data received", message); 
       }else if(meta.equalsIgnoreCase("Binary")){ 
        InputStream is = socket.getInputStream(); 
        ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
        byte[] buf = new byte[4096]; 
        int len; 
        while((len=is.read(buf))>-1){ 
         stream.write(buf,0,len); 
        } 
        stream.flush(); 

        //read object input 
        try { 
         ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(stream.toByteArray())); 
         byte[] buffer = (byte[])ois.readObject(); 
         FileOutputStream fos = new FileOutputStream("/storage/emulated/0/DCIM/IMG-Saved.jpeg"); 
         fos.write(buffer); 
        }catch (ClassNotFoundException e){ 
         e.printStackTrace(); 
        } 
        finally { 
         Log.i("Binary_Transfer","File created"); 
        } 
       } 
      } 
     } catch (IOException e){ 
      e.printStackTrace(); 
     }finally { 
      Log.i("Client_Socket","Stream will close"); 
      if(dis!=null){ 
       try { 
        dis.close(); 
       }catch (IOException e){ 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 

对于文本和二进制数据,发送数据之前,客户端将发送的文本元数据,通知数据是文本或二进制服务器。但是在接收到一个文件(image)后,它会在行中引发一个EOFException:String meta = dis.readUTF();我猜它是因为读取和写入二进制文件后,线程继续循环,所以DataInputStream将再次读取,现在没有什么可以接收,所以readUTF()抛出EOFException。在发送二进制文件以让DataInputStream可以读取某些内容并且不抛出异常之后,我尝试从客户端发送元数据,但它不起作用,客户端确实发送了元数据,但服务器仍然抛出EOFException。任何人都知道问题是什么?非常感谢。

下面是从客户端我发送二进制方法:

public void sendBinaryData(byte[] binaryData){ 
    if(dos!=null && socket!=null){ 
     try { 
      ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 
      oos.writeObject(binaryData); 
      Log.d("Binary_Transfer", "C: Sent."); 
      oos.close(); 
      dos.writeUTF("Binary_End"); 
      dos.flush(); 
     }catch (Exception e){ 
      Log.e("File_Exception",e.toString()); 
     } 
    } 
} 

回答

1

因为当你开始读二进制数据,你进入一个循环,只有终止在流,即结束的时候,同行断开:

while((len=is.read(buf))>-1){ 
    stream.write(buf,0,len); 
} 

在那一点,你在流的结尾。没有更多的数据,没有更多的数据,并且永远不会有更多的数据。

您需要彻底删除这一部分:

InputStream is = socket.getInputStream(); 
ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
byte[] buf = new byte[4096]; 
int len; 
while((len=is.read(buf))>-1){ 
    stream.write(buf,0,len); 
} 
stream.flush(); 

很少有阅读任何东西点进去ByteArrayOutputStreams无论如何,这也不例外。只是删除完全,并更改下一部分:

ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(stream.toByteArray())); 

ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 

,并继续为你了。但是,您有另一个问题:

oos.close(); 

这会关闭套接字。所以下一部分:

dos.writeUTF("Binary_End"); 
dos.flush(); 

不可能工作。只需冲洗ObjectOutputStream而不是关闭它。

但我强烈建议你丢弃DataInput/OutputStreams并在插座的两端使用一个单独的ObjectInput/OutputStream

+0

当然,关键的一点是OP应该使用readObject()来读取接收端的byte []。 – jtahlborn 2014-09-01 04:26:41

+0

@jtahlborn阅读他的代码。这正是他已经在做的。他的问题是之前的垃圾,并关闭了ObjectOutputStream。 – EJP 2014-09-01 04:43:01

+0

啊,在嵌套的对象流中。出于某种原因,昨晚我也掩盖了这一点。 – jtahlborn 2014-09-01 13:58:28

相关问题