1

我在寫簡單的客戶端 - 服務器應用程序。一切都很好,但是當我將InputStream和OutputStream更改爲ObjectOutputStream和ObjectInputStream時,我的應用程序不會發送消息。任何人都可以幫助我並向我展示問題嗎?Socket ObjectOutpuStream ObjectInputStream

這裏是Serwer.java:

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:

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

檢查的ObjectInputStream構造:constructor
它說:

此構造方法將阻塞,直到相應的ObjectOutputStream 寫和沖洗頭。

所以你需要創建並刷新相應的ObjectOutputStream。現在您在輸出流之前爲服務器和客戶端創建ObjectInputStreams。他們阻止程序,因爲沒有輸出流創建。您應該先創建輸出流,然後調用flush,然後才能創建輸入流。

+0

AFAIK沒有必要調用'flush()',實現它本身 –

+0

它的工作原理沒有'flush()',但ObjectOutputStream'的構造函數的文檔說:「...調用者可能希望立即刷新流以確保接收ObjectInputStreams的構造函數不會阻止...」 –

+0

我改變順序在服務器和客戶機中):'嘗試{O^= 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指出的一樣。實施解決方案是讓服務器和客戶端以相反的順序獲取輸入和輸出流。如果一個人首先獲得輸入流,另一個獲得輸出流等。我切換客戶端以首先獲得輸出流,並且一切正常。然後我把它放回去並更換服務器,並且這一切都以這種方式運行...您可以選擇要更改的設備。

相關信息: http://docs.oracle.com/javase/6/docs/api/index.html?java/io/ObjectOutputStream.html

+0

兩者都應該首先打開ObjectOutputStream才能安全 –