2012-07-08 150 views
1

我正試圖保持多線程服務器程序的連接打開狀態。當我點擊一個按鈕時,我希望它向所有連接的客戶端發送測試消息。與套接字保持連接

public void run() { 
    try { 
     Scanner in = new Scanner(socket.getInputStream()); 
     PrintWriter out = new PrintWriter(socket.getOutputStream()); 
     readUpdate(out, in); 
     while(true){sendUpdate(out);} 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

使用多CPU的方式。

這是我的sendUpdate方法。

private void sendUpdate(final PrintWriter out) { 
    new Thread(new Runnable() { 

     public void run() { 
      if(Server.send) { 
       try { 
        if (Server.command != "idle") { 
         System.out.println("Sending"); 
         out.println("[email protected]" + Server.command); 
         out.flush(); 
         Server.send = false; 
         Thread.sleep(100); 
        } 
       } catch (Exception ex) { 
       } 
      } 
     } 
    }).start(); 
} 

如果有人可以幫助我保持連接打開,並準備發送數據,我將不勝感激。

+1

'而(真){sendUpdate(出);}'創造這麼多線程這個產量:o ..只是不創建'setUpdate()'方法中的新線程。 – 2012-07-08 16:19:38

+0

套接字將保持打開狀態,直到您或客戶端關閉它爲止。將循環移到線程的'run'方法中。 – 2012-07-08 16:46:34

+0

我試過了,我幫了忙,但是我的CPU使用率每個客戶端連接了大約80%,我只能連接四個。 – user1497561 2012-07-08 16:53:54

回答

1

如果您的服務器可以發起消息,客戶端也可以發起消息,那麼您可能需要單獨的線程讀取和寫入。一個線程對於請求 - 響應風格的通信很有意義,您可以阻止下一個客戶端請求,執行一些服務器端處理,響應客戶端,然後再次阻止。

但是,如果您需要在兩個單獨的條件(從客戶端接收消息並單擊服務器上的按鈕)上阻止,則應該有兩個單獨的線程。否則,你會發現自己需要反覆喚醒你的線程來檢查是否有任何一個條件是真的。

因此,創建兩個線程,並給一個你的Scanner(即readUpdate邏輯)和其他你的PrintWriter。這是你的輸出處理程序可以是什麼樣子:

public class WriteHandler implements Runnable { 
    private final PrintWriter out; 
    private final BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>(); 

    //initialize the above in a constructor; 

    public void run() { 
     while(true) { 
      String nextMessageToWrite = messageQueue.poll(); 
      out.println(nextMessageToWrite); 
     } 
    } 

    public void send(String message) { 
     messageQueue.add(message); 
    } 
} 

這將使用blocking queue,比支票睡眠循環更好的併發機制。然後單擊該按鈕時,你可以有這樣的事情:

public void actionPerformed() { 
    for (WriteHandler handler : handlers) { 
     handler.send("PING!"); 
    } 
}