0

클라이언트에서 텍스트 및 바이너리 데이터를 모두받을 서버를 만듭니다. 바이너리 파일을받는 첫 번째뿐만 아니라 텍스트 데이터와도 작동하지만 이후에는 계속 데이터를 읽지 않고 예외를 throw합니다. 데이터를 전송하기 전에, 클라이언트가 데이터를 텍스트 또는 이진 서버를 알려 텍스트 메타 데이터를 전송합니다, 텍스트와 바이너리 데이터를 모두 들어왜 바이너리 파일을 읽은 후에 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(); 
       } 
      } 
     } 
    } 
} 

: 여기 내 서버 코드입니다. 그러나 파일 (이미지)을받은 후에는 다음 줄에 EOFException을 발생시킵니다. String meta = dis.readUTF(); 나는 이진 파일을 읽고 쓰고 난 후에 쓰레드가 루프를 계속해서하므로 DataInputStream이 다시 읽을 것이므로 readUTF()가 EOFException을 던질 것이기 때문에 아무 일도 일어나지 않았기 때문에 일어난 것 같다. DataInputStream이 뭔가를 읽을 수 있고 예외를 throw하지 못하게하려면 이진 파일을 보낸 후 클라이언트에서 메타 데이터를 보내려고했지만 클라이언트가 메타 데이터를 보내지 만 서버가 여전히 EOFException을 throw합니다. 문제가 무엇인지 아는 사람이 있습니까? 정말 고마워. 여기

클라이언트에서 내 보낼 바이너리 방법 :

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

+0

@jtahlborn 코드를 읽으십시오. 그것이 바로 그가 이미하고있는 일입니다. 그의 문제는 그 전에 쓰레기이며,'ObjectOutputStream'을 닫습니다. – EJP

+0

아아, 중첩 된 객체 스트림 내부. 웬일인지 지난 밤에 나는 그걸 지나치게 썼다. – jtahlborn

관련 문제