0

这一定很容易,但我显然缺少一些基本的理解。我有简单的客户端服务器应用程序

服务器:

public class GameServer{
   private Socket clientSocket;
   private ServerSocket serverSocket;
   private ArrayList<ObjectOutputStream> oosPlayers=new ArrayList<ObjectOutputStream>();   

   public static void main(String args[]){
       GameServer server = new GameServer();
       server.startGame();
   }   

   public void startGame(){  
      try{
         serverSocket = new ServerSocket(10008);  
         System.out.println("Server started at:" + serverSocket);
         while(true){
             System.out.println("Server: Waiting for client requests...");
             clientSocket=serverSocket.accept();
             System.out.println("Server: Client connection accepted at:"+clientSocket);
             //remember player's output stream
             oosPlayers.add(new ObjectOutputStream(clientSocket.getOutputStream()));
             //read data from clients 
             Thread receiverThread = new Thread(new DataReceiver());
             receiverThread.start();
         }
      }
      catch(IOException ex){
          System.out.println(ex.getMessage());
      }
   }
   public class DataReceiver implements Runnable{
       public void run(){
           try{
               String mess;
               ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
               while((mess=(String)ois.readObject()) != null){                         
                   System.out.println("Server: "+mess);
                   send();
               }
           }
           catch(Exception ex){ System.out.println(ex.getMessage()); }
       }
       public void send(){
           for (ObjectOutputStream oos : oosPlayers){
               try{
                   oos.writeObject(new String("There is "+oosPlayers.size()+" player(s) at the board"));                   
                   oos.flush();
               }
               catch(Exception ex){ System.out.println(ex.getMessage()); }  
           }
       }
   }        
}

客户:

public class GameClient implements ActionListener{
   private Socket socket;
   private ObjectInputStream  ois;
   private ObjectOutputStream oos;
   private JButton button;

   public static void main(String args[]){
       GameClient client = new GameClient();  
       client.drawBoard();
   }
   public void drawBoard(){
       JFrame frame = new JFrame("A game");
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       button = new JButton("Send");
       button.addActionListener(this);
       configureConnection();
       Thread receiverThread = new Thread(new DataReceiver());
       receiverThread.start();

       frame.getContentPane().add(new JPanel().add(button));
       frame.setSize(200,200);
       frame.setVisible(true);
   }   
   public void configureConnection(){
       try{
           socket = new Socket("127.0.0.1", 10008);
           ois = new ObjectInputStream(socket.getInputStream());
           oos = new ObjectOutputStream(socket.getOutputStream());
       }
       catch(Exception ex) { System.out.println(ex.getMessage()); }
   }   

   public void actionPerformed(ActionEvent ev){
       if (ev.getSource()==button){
          try{
              oos.writeObject(new String("Some data from client"));
              oos.flush();
          }
          catch(Exception ex){ System.out.println(ex.getMessage()); }         
       }
   }   

   public class DataReceiver implements Runnable{
       public void run(){
           try{
               String mess;
               while((mess=(String)ois.readObject())!= null){                  
                   System.out.println("Client:"+mess);
               }
           }
           catch(Exception ex){ System.out.println(ex.getMessage()); }
       }
   }   
}

我的问题与双方的receiverThread有关。当我在从ObjectInputStream读取期间(在 RUN 方法中)使用 WHILE 时,服务器会侦听客户端请求并将它们正确分派到所有ObjectOutputStream。如果我将此WHILE更改为IF数据,则每个客户端仅从服务器读取(并发送)一次。这同样适用于客户端的 WHILE/IF。

我的理解是,当我运行receiverThread时,它以某种方式在 WHILE 停止线程并继续从输入流中读取,而使用 IF 让线程完成(从而停止读取过程)。尽管不满足 WHILE 条件,即最初(还没有客户端连接),但它使receiverThread保持活动状态,这怎么可能呢?在receiverThread 已经读取数据并且流中没有任何内容之后也会发生同样的情况。

希望能对这个基本问题做出一些解释。

问候马辛

4

1 回答 1

0

如果您在run()方法中将 while 更改为 if,则您只读取一个对象并退出。如果您的客户端-服务器协议非常简单,例如它们每个会话只发送一个对象,则两个版本是相等的。否则系统将无法正常运行:所有其他对象都不会到达。

于 2011-11-03T15:12:24.033 回答