2010-02-07 79 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。