2011-08-11 103 views
5

好吧,我有一個線程類叫做'客戶端',每當服務器接受連接時它會創建一個新的客戶端....運行方法監聽來自客戶端的消息,我我期運用ObjectInputStream的..Java - 用ObjectInputStream監聽套接字

do {    
     ObjectInputStream in = null; 

     try { 
      in = new ObjectInputStream(socket.getInputStream()); 
      String message = (String) in.readObject(); 
      System.out.println(message); 
      } 
      catch (ClassNotFoundException ex) { 
       isConnected = false; 
       System.out.println("Progoramming Error"); 
      } 
      catch (IOException ex) { 
       isConnected = false; 
       System.out.println("Server ShutDown"); 
       System.exit(0); 
      } 
    } while(isConnected); 

這個問題我有是,爲什麼我要創建一個新的ObjectInputStream每次循環的時間......如果我在循環結束時關閉輸入流,並循環再次爲另一個消息,我會得到一個錯誤...請幫助一下

+2

你不必,而你不應該。 –

+1

並且獲取ClassNotFoundException既不表示您已連接,也不會出現編程錯誤。它表示一個*部署*錯誤。 – EJP

+0

你可以通過什麼樣的錯誤獲得,如果你發佈了客戶端代碼,它也會有所幫助。 – beny23

回答

6

只爲客戶端連接創建ObjectInputStream一次(循環外),然後把將readObject方法放入循環中。

這裏的工作測試類:

public class TestPrg { 

    public static void main(String... args) throws IOException { 
     ServerListener server = new ServerListener(); 
     server.start(); 

     Socket socketToServer = new Socket("localhost", 15000); 
     ObjectOutputStream outStream = new ObjectOutputStream(socketToServer.getOutputStream()); 

     for (int i=1; i<10; i++) { 
      try { 
       Thread.sleep((long) (Math.random()*3000)); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("Sending object to server ..."); 
      outStream.writeObject("test message #"+i); 
     } 
     System.exit(0); 

    } 

    static class ServerListener extends Thread { 

     private ServerSocket serverSocket; 

     ServerListener() throws IOException { 
      serverSocket = ServerSocketFactory.getDefault().createServerSocket(15000); 
     } 

     @Override 
     public void run() { 
      while (true) { 
       try { 
        final Socket socketToClient = serverSocket.accept(); 
        ClientHandler clientHandler = new ClientHandler(socketToClient); 
        clientHandler.start(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

    static class ClientHandler extends Thread{ 
     private Socket socket; 
     ObjectInputStream inputStream; 

     ClientHandler(Socket socket) throws IOException { 
      this.socket = socket; 
      inputStream = new ObjectInputStream(socket.getInputStream()); 
     } 

     @Override 
     public void run() { 
      while (true) { 
       try { 
        Object o = inputStream.readObject(); 
        System.out.println("Read object: "+o); 
       } catch (IOException e) { 
        e.printStackTrace(); 

       } catch (ClassNotFoundException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

} 

在這個例子中的字符串被送到低谷ObjectStream。如果您得到ClassNotFoundException(http://download.oracle.com/javase/6/docs/api/java/io/ObjectInputStream.html#readObject())並且正在使用獨立的客戶端和服務器程序,則可能會檢查是否客戶端和服務器都有要在其類路徑中發送的對象的類。

+0

ohhh我seee ...謝謝你的朋友..我會稍後嘗試..並告訴你它是怎麼回事.... – MurWade

+0

我試過了,它沒有工作.... – MurWade

+1

睡眠是毫無意義的,讀取循環應該捕獲'EOFException',並在捕獲時跳出讀取循環。除'SocketTimeoutException'之外的所有其他'IOExceptions'對連接也是致命的,應該退出讀循環。讀取循環出於任何原因後應該關閉套接字。這裏太糟糕的做法。 – EJP