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に適切にディスパッチします。このWHILEIFに変更すると、データは各クライアントごとに 1 回だけサーバーから読み取られます (そして送信されます)。同じことがクライアントの WHILE/IF にも当てはまります。

私の理解では、receiverThreadを実行すると、WHILE でスレッドが何らかの形で停止し、入力ストリームからの読み取りが続行されますが、IF を使用するとスレッドが終了します (したがって、読み取りプロセスが停止します)。WHILE 条件が満たされていなくても、つまり最初は (まだクライアントが接続されていない)、receiverThreadが生きている可能性はありますか。同じことが、receiverThread が既にデータを読み取り、ストリームに何も残っていない場合にも発生します。

この基本的な問題について説明をいただければ幸いです。

よろしくマルシン

4

1 に答える 1

0

メソッド内で while を if に変更すると、run()1 つのオブジェクトだけを読み取って終了します。クライアント サーバー プロトコルが非常に単純な場合、たとえば、セッションごとに 1 つのオブジェクトのみを送信する場合、両方のバージョンは同じです。そうしないと、システムが正しく機能しません。他のすべてのオブジェクトが到着しません。

于 2011-11-03T15:12:24.033 に答える