1

간단한 클라이언트 - 서버 응용 프로그램을 작성하고 있습니다. 모든 것은 괜찮습니다.하지만 InputStream과 OutputStream을 ObjectOutputStream과 ObjectInputStream으로 변경하면 응용 프로그램이 메시지를 보내지 않습니다. 누구든지 나를 도와주고 문제를 보여줄 수 있습니까?소켓 ObjectOutpuStream ObjectInputStream

class InWorke implements Runnable{ 

    BufferedReader odczyt=null; 
    String slowo; 
    ObjectInputStream ois=null; 
    Message message; 

    InWorke(ObjectInputStream ois) { 
     this.ois=ois; 
    } 

    public void run() { 
     while(true) { 
      try { 
       slowo = (String) ois.readObject(); 
      } catch (ClassNotFoundException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      System.out.println(slowo); 
      Thread.yield(); 
     }    } 

} 

class OutWorke implements Runnable{ 
    Socket socket=null; 
    BufferedReader odczytWe=null; 
    DataOutputStream zapis=null; 
    String slowo=null; 
    Message message; // it is the simple class to serialization 
    ObjectOutputStream oos; 

    OutWorke(Socket socket,ObjectOutputStream oos) { 
     this.socket=socket; 
     this.oos=oos; 
    } 

    public void run() { 
     while(true) { 
      odczytWe=new BufferedReader(new InputStreamReader(System.in)); 
      try { 
       slowo=odczytWe.readLine(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      try { 
        oos.writeObject(slowo); 
        oos.flush(); 
       } catch (IOException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 
      Thread.yield(); 

    } 

} 
} 

public class Klient { 
    public static void main(String[] args) { 

    Socket socket=null; 
    ExecutorService exec=Executors.newCachedThreadPool(); 

    ObjectOutputStream oos=null; 
    ObjectInputStream ois=null; 

    try { 
     socket=new Socket("localhost", 8881); 
    } catch (UnknownHostException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    try { 
     //we=socket.getInputStream(); 
     ois=new ObjectInputStream(socket.getInputStream()); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    try { 
     //wy=socket.getOutputStream(); 
     oos=new ObjectOutputStream(socket.getOutputStream()); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    exec.execute(new OutWorke(socket, oos)); 
    exec.execute(new InWorke(ois)); 

} 
} 

Klient.java : ObjectInputStream

class InWorker implements Runnable{ 

    Socket socket=null; 
    //InputStream we=null; 
    //OutputStream wy=null; 
    String slowo=null; 
    BufferedReader odczyt=null; 
    ObjectOutputStream oos; 
    ObjectInputStream ois; 
    Message message=null; 

    InWorker(Socket socket,ObjectInputStream ois) { 
     this.socket=socket; 
     this.ois=ois; 
    } 

    public void run() { 
       while(true) { 
       try { 
        slowo=(String) ois.readObject(); 
       } catch (ClassNotFoundException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       System.out.println(slowo); 
       Thread.yield(); 
      } 

      } 
} 

class OutWorker implements Runnable{ 

    DataOutputStream zapis=null; 
    BufferedReader odczyt=null; 
    //OutputStream wy=null; 
    String tekst=null; 
    ObjectOutputStream oos=null; 
    Message message; 

    OutWorker(ObjectOutputStream oos) { 
     this.oos=oos; 
    } 

    public void run() { 
     while(true) { 
     odczyt=new BufferedReader(new InputStreamReader(System.in)); 
     try { 
      tekst=odczyt.readLine(); 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
     try { 
      oos.writeObject(tekst); 
      oos.flush(); 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
     Thread.yield(); 
     } 
    } 

} 

public class Serwer { 

    public static void main(String[] args) { 
     ServerSocket serversocket=null; 
     Socket socket=null; 
     //InputStream we=null; 
     //OutputStream wy=null; 
     ObjectOutputStream oos=null; 
     ObjectInputStream ois=null; 

     ExecutorService exec=Executors.newCachedThreadPool(); 

     try { 
      serversocket=new ServerSocket(8881); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      socket=serversocket.accept(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      ois=new ObjectInputStream(socket.getInputStream()); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      oos=new ObjectOutputStream(socket.getOutputStream()); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     exec.execute(new InWorker(socket, ois)); 
     exec.execute(new OutWorker(oos)); 

    } 

} 
+0

그리고 무엇 : 참조를 들어

? 오류? – kinaesthesia

+0

컴파일러에서 오류 또는 예외를 표시하지 않습니다. 프로그램이 실행되었지만 작동하지 않습니다. – user1518451

+0

가능한 새 [ObjectInputStream() 블록 중복] (http://stackoverflow.com/questions/14110986/new-objectinputstream-blocks) –

답변

4

확인 생성자 : constructor 다음

는 Serwer.java입니다.
는 말한다 : 해당 ObjectOutputStream에 가 헤더를 기입 해 플래시 할 때까지

이 생성자가 차단합니다.

따라서 해당 ObjectOutputStream을 만들고 플러시해야합니다. 이제 서버와 클라이언트 둘 다에 대한 출력 스트림 전에 ObjectInputStream을 생성하고 있습니다. 출력 스트림이 생성되지 않기 때문에 프로그램을 차단합니다. 먼저 출력 스트림을 작성하고 flush을 호출 한 다음 입력 스트림을 작성해야합니다.

+0

AFAIK 'flush()'를 호출 할 필요가 없습니다. 구현 자체는 그 자체입니다 –

+0

"flush()"가 없어도 동작하지만, "ObjectOutputStream"의 생성자에 대한 문서에서는 "... 호출자는 스트림을 즉시 플러시하여 ObjectInputStreams를 수신하는 생성자가 차단되지 않도록 할 수 있습니다." –

+0

주문을 변경합니다 서버 및 클라이언트에서) : {try { \t \t \t oos = new ObjectOutputStream (socket.getOutputStream()); \t \t \t oos.flush(); \t \t} 캐치 (IOException이 전자) { \t \t \t // TODO) (catch 블록을 \t \t \t e.printStackTrace을 자동 생성; \t \t} \t \t 시도 { \t \t \t OIS = 새로운 ObjectInputStream에 (socket.getInputStream()); \t \t} 캐치 (IOException이 전자) { \t \t \t // TODO catch 블록을 \t \t \t 전자를 자동 생성.printStackTrace(); \t \t} 그러나 프로그램은 여전히 ​​작동하지 않습니다. – user1518451

1

근본적인 문제는 Nikita가 지적한 것과 같습니다. 구현 솔루션은 서버와 클라이언트가 입력 스트림과 출력 스트림을 반대 순서로 얻도록하는 것입니다. 입력 스트림을 먼저 얻는다면 다른 하나는 outputstream을 얻습니다. 클라이언트를 먼저 출력 스트림을 얻도록 전환하면 모든 것이 작동합니다. 그런 다음 서버를 다시 넣고 서버를 변경하면 모든 작업이 ... 변경할 대상을 선택할 수 있습니다. 예외에 대한 http://docs.oracle.com/javase/6/docs/api/index.html?java/io/ObjectOutputStream.html

+0

두 가지 모두 ObjectOutputStream을 먼저 열어야 안전합니다. –