2010-02-04 94 views
0

基本上我有一個基本的Java Socket服務器,如下所示。它允許多個用戶進行連接,並在他們發送消息時將其返回。但是我想知道如何編輯它,所以如果用戶向它發送消息,而不是僅僅發送回它將它發送給所有連接的人?所以基本的聊天服務器。任何幫助將不勝感激:)如何將消息發送給多個用戶?

import java.awt.Color; 
import java.awt.BorderLayout; 
import java.awt.event.*; 
import javax.swing.*; 

import java.io.*; 
import java.net.*; 

class ClientWorker implements Runnable { 
    private Socket client; 
    private JTextArea textArea; 

    ClientWorker(Socket client, JTextArea textArea) { 
    this.client = client; 
    this.textArea = textArea; 
    } 

    public void run(){ 
    String line; 
    BufferedReader in = null; 
    PrintWriter out = null; 
    try{ 
     in = new BufferedReader(new InputStreamReader(client.getInputStream())); 
     out = new PrintWriter(client.getOutputStream(), true); 
    } catch (IOException e) { 
     System.out.println("in or out failed"); 
     System.exit(-1); 
    } 

    while(true){ 
     try{ 
     line = in.readLine(); 
//Send data back to client 
     out.println(line); 
     textArea.append(line); 
     } catch (IOException e) { 
     System.out.println("Read failed"); 
     System.exit(-1); 
     } 
    } 
    } 
} 

class SocketThrdServer extends JFrame{ 

    JLabel label = new JLabel("Text received over socket:"); 
    JPanel panel; 
    JTextArea textArea = new JTextArea(); 
    ServerSocket server = null; 

    SocketThrdServer(){ //Begin Constructor 
    panel = new JPanel(); 
    panel.setLayout(new BorderLayout()); 
    panel.setBackground(Color.white); 
    getContentPane().add(panel); 
    panel.add("North", label); 
    panel.add("Center", textArea); 
    } //End Constructor 

    public void listenSocket(){ 
    try{ 
     server = new ServerSocket(4444); 
    } catch (IOException e) { 
     System.out.println("Could not listen on port 4444"); 
     System.exit(-1); 
    } 
    while(true){ 
     ClientWorker w; 
     try{ 
     w = new ClientWorker(server.accept(), textArea); 
     Thread t = new Thread(w); 
     t.start(); 
     } catch (IOException e) { 
     System.out.println("Accept failed: 4444"); 
     System.exit(-1); 
     } 
    } 
    } 

    protected void finalize(){ 
//Objects created in run method are finalized when 
//program terminates and thread exits 
    try{ 
     server.close(); 
    } catch (IOException e) { 
     System.out.println("Could not close socket"); 
     System.exit(-1); 
    } 
    } 

    public static void main(String[] args){ 
     SocketThrdServer frame = new SocketThrdServer(); 
    frame.setTitle("Server Program"); 
     WindowListener l = new WindowAdapter() { 
       public void windowClosing(WindowEvent e) { 
         System.exit(0); 
       } 
     }; 
     frame.addWindowListener(l); 
     frame.pack(); 
     frame.setVisible(true); 
     frame.listenSocket(); 
    } 
} 

回答

0

您可以通過提供一個持有人來容納所有客戶端添加一點修改。可以是List實現。然後,您可以編寫廣播方法並調用該方法,而不是out.println()。在這種方法中,你會按照這種方式做類似的事情。

此外,您應該查看Observer Pattern以有效實施此功能,此外您還將對設計模式有很好的理解。另一種有用的模式是Mediator Pattern

+0

對不起,如果這聽起來很粗魯,但我會怎麼做呢?我對Java很陌生,而且我正在構建一個服務器來與另一個項目一起使用,這是最後一點,我真的想完成它:) – Ozzie 2010-02-04 10:07:35

+0

不知道你的整體設計,我不能爲你提供任何確切的建議。所以,看看這裏http://www.codeproject.com/KB/IP/c_sharp_remoting.aspx。它是基於Observer模式使用.NET的聊天應用程序示例。肯定會給你一個很好的提示。 – 2010-02-04 10:12:27

+0

好的,謝謝!我會看一看!。這是整個程序哈哈 – Ozzie 2010-02-04 10:50:09

0

每次創建listenSocketClientWorker,保持所有的客戶端工人有權訪問列表到客戶端的引用(無論是在全球還是 - 最好 - 傳遞到他們在創建時)。當客戶收到一條消息時,它可以在列表中循環並將消息發回給每個工作人員。在添加/刪除/遍歷這個列表時,你需要小心,因爲你將會運行很多線程,這些線程都可以在同一時間嘗試並訪問它。

此外,爲了正確起見,您應該從EDT而不是從客戶端線程訪問Swing組件(例如textArea.appendClientWorker)。查看javadocs的SwingUtilities.invokeLater