2011-08-11 100 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