2010-02-07 74 views
1

本質上,我已經構建了一個套接字服務器,多個客戶端可以連接到,並且當他們發送消息到服務器時,它會發送到每個其他客戶端。問題是它還沒有工作。我需要整理「SingletonClients」和「getClients」,以便他們返回所有已連接的用戶,準備好向我發送消息。這只是一個基本的問題,但我完全不知道如何去做,它是我正在做的學生項目的最後一部分(主要部分是Obj-C客戶端,而不是Java服務器)。如果有人能爲我做到這一點,我會永遠感激。需要服務器和鏈接列表幫助

繼承人的代碼至今:

import java.awt.Color; 
import java.awt.BorderLayout; 
import java.awt.event.*; 
import javax.swing.*; 
import java.util.LinkedList; 
import java.io.*; 
import java.net.*; 

class ClientWorker implements Runnable { 
    private Socket client; 
    private JTextArea textArea; 
    BufferedReader in = null; 
    PrintWriter out; 

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

     String line = in.readLine(); 
     LinkedList<ClientWorker> clients = SingletonClients.getClients(); 
     for(int i = 0; i < clients.size(); i++) { 
      ClientWorker c = clients.get(i); 
      //The client doesn't need to get it's own data back. 
      if(c == this){ 
       continue; 
      } 
      c.writeString(line); 
     } 

    } 

    public void writeString(String s) { 
     try { 
      out.println(s); 
     } catch(IOException ex) { 
     } 
    } 

    public void run(){ 
     String line; 
     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(); 
    } 
} 

提前感謝!

回答

1
LinkedList<ClientWorker> clients = SingletonClients.getClients(); 

因爲它好像你需要的東西,返回ClientWorker的集合,我建議您通過您的代碼查找在其中創建ClientWorkers和嘗試,並把它們集合在一個地方。

這有道理嗎?

0

你會想要注意你的ClientWorker課程的開始。在你的領域的聲明部分中,您聲明一些實例成員,像這樣:

BufferedReader in = null; 
PrintWriter out; 

但隨後在構造函數中,您嘗試使用它們無需先初始化它們:

String line = in.readLine(); //will throw a NullPointerException 
    LinkedList<ClientWorker> clients = SingletonClients.getClients(); 
    for(int i = 0; i < clients.size(); i++) { 
     ClientWorker c = clients.get(i); 
     //The client doesn't need to get it's own data back. 
     if(c == this){ 
      continue; 
     } 
     c.writeString(line); //calls out.println, will throw a NullPointerException 
    } 

至於你SingletonWorker,如果這是項目的一部分,那麼您可能會被要求在Java中創建一個單例。這並不是什麼大問題,但顯然有一件事情需要確保 - 只允許在流程生命週期中創建一個單例實例。看看here的一些想法。另一方面,如果SingletonWorker是您設計的助手,那麼您最好跟在@ willcodejavaforfood的領先地位並製作一個類型安全的LinkedList。