Java: приложение клиент-сервер. WHILE в потоке чтения ObjectInputStream - PullRequest
0 голосов
/ 03 ноября 2011

Это должно быть очень легко, но мне явно не хватает некоторого базового понимания.У меня есть простое клиент-серверное приложение

сервер:

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()); }
       }
   }   
}

Мой вопрос относится к receiveThread с обеих сторон.Когда я использую WHILE во время чтения из ObjectInputStream (в методе RUN), сервер прослушивает запросы клиентов и правильно отправляет их всем ObjectOutputStream с.Если я изменю это значение WHILE на IF , данные будут считываться (и отправляться) с сервера только один раз для каждого клиента.То же самое относится к клиентскому WHILE / IF.

Насколько я понимаю, когда я запускаю receiverThread , он каким-то образом останавливает поток в WHILE и продолжает чтение из входного потока, тогда как при использовании IF давайте потокузакончить (и тем самым останавливает процесс чтения).Как это возможно, что хотя условие WHILE не выполняется, то есть изначально (ни один клиент еще не подключен), оно поддерживает receiveThread в действии.То же самое происходит после того, как receiveThread уже прочитал данные, и в потоке ничего не осталось.

Буду признателен за некоторые пояснения по этой основной проблеме.

С уважением, Марцин

1 Ответ

0 голосов
/ 03 ноября 2011

Если вы измените while на if, если в вашем методе run() вы прочитаете только один объект и выйдите. Если ваш клиент-серверный протокол очень прост, например, они посылают только один объект за сеанс, обе версии равны. В противном случае система не будет функционировать должным образом: все остальные объекты не будут доставлены.

...