向所有客户端发送消息(客户端 – 服务器通信)

所以现在,我正在制作一个基于multithreading的客户端服务器应用程序。 在服务器端,我为接受的单独连接创建了一个线程。

在线程类中,我创建了一个向客户端发送命令的方法。 我只想要的是,如何向所有正在运行的客户端发送参数? 对于简单的声明,我只想让这个服务器向所有连接的客户端发送消息。

我已阅读此帖并从此链接中找到sendToAll(String message)方法。 但是当我尝试使用我的代码时,在ServerSocket没有类似的方法。

好的,这是我的服务器和线程的示例代码。

 class ServerOne{ ServerSocket server = null; ... ServerOne(int port){ System.out.println("Starting server on port "+port); try{ server = new ServerSocket(port); System.out.println("Server started successfully and now waiting for client"); } catch (IOException e) { System.out.println("Could not listen on port "+port); System.exit(-1); } } public void listenSocket(){ while(true){ ClientWorker w; try{ w = new ClientWorker(server.accept()); Thread t = new Thread(w); t.start(); } catch (IOException e) { System.out.println("Accept failed: 4444"); System.exit(-1); } } } protected void finalize(){ try{ server.close(); } catch (IOException e) { System.out.println("Could not close socket"); System.exit(-1); } } } class ClientWorker implements Runnable{ Socket client; ClientWorker(Socket client){ this.client = client; } public void run(){ ... sendCommand(parameter); ... } public void sendCommand(String command){ PrintWriter out = null; try { out = new PrintWriter(client.getOutputStream(), true); out.println(command); } catch (IOException ex) {} } } 

感谢帮助 :)

对于完整的服务器,建议不要使用以下答案,因此您应该将Java EE与servlet,Web服务等一起使用。

这仅适用于少数计算机要连接以执行特定任务的情况,并且使用简单的Java套接字不是一般问题。 想想分布式计算或多人游戏。

编辑:我 – 从第一篇文章 – 大大更新了这个架构,现在测试和线程安全。 任何需要它的人都可以在这里下载。

只需使用(直接或通过子类化) ServerClientstart()它们,一切就绪。 阅读内联注释以获得更强大的选项。


虽然客户之间的沟通相当复杂,但我会尽量简化它。

以下是服务器中的要点:

  • 保持已连接客户端的列表。
  • 为服务器输入定义一个线程。
  • 定义接收消息的队列。
  • 从队列中轮询的线程,并使用它。
  • 一些用于发送消息的实用方法。

对于客户:

  • 为客户端输入定义一个线程。
  • 定义接收消息的队列。
  • 从队列中轮询的线程,并使用它。

这是Server类:

 public class Server { private ArrayList clientList; private LinkedBlockingQueue messages; private ServerSocket serverSocket; public Server(int port) { clientList = new ArrayList(); messages = new LinkedBlockingQueue(); serverSocket = new ServerSocket(port); Thread accept = new Thread() { public void run(){ while(true){ try{ Socket s = serverSocket.accept(); clientList.add(new ConnectionToClient(s)); } catch(IOException e){ e.printStackTrace(); } } } }; accept.setDaemon(true); accept.start(); Thread messageHandling = new Thread() { public void run(){ while(true){ try{ Object message = messages.take(); // Do some handling here... System.out.println("Message Received: " + message); } catch(InterruptedException e){ } } } }; messageHandling.setDaemon(true); messageHandling.start(); } private class ConnectionToClient { ObjectInputStream in; ObjectOutputStream out; Socket socket; ConnectionToClient(Socket socket) throws IOException { this.socket = socket; in = new ObjectInputStream(socket.getInputStream()); out = new ObjectOutputStream(socket.getOutputStream()); Thread read = new Thread(){ public void run(){ while(true){ try{ Object obj = in.readObject(); messages.put(obj); } catch(IOException e){ e.printStackTrace(); } } } }; read.setDaemon(true); // terminate when main ends read.start(); } public void write(Object obj) { try{ out.writeObject(obj); } catch(IOException e){ e.printStackTrace(); } } } public void sendToOne(int index, Object message)throws IndexOutOfBoundsException { clientList.get(index).write(message); } public void sendToAll(Object message){ for(ConnectionToClient client : clientList) client.write(message); } } 

这里是Client类:

 public class Client { private ConnectionToServer server; private LinkedBlockingQueue messages; private Socket socket; public Client(String IPAddress, int port) throws IOException{ socket = new Socket(IPAddress, port); messages = new LinkedBlokingQueue(); server = new ConnecionToServer(socket); Thread messageHandling = new Thread() { public void run(){ while(true){ try{ Object message = messages.take(); // Do some handling here... System.out.println("Message Received: " + message); } catch(InterruptedException e){ } } } }; messageHandling.setDaemon(true); messageHandling.start(); } private class ConnectionToServer { ObjectInputStream in; ObjectOutputStream out; Socket socket; ConnectionToServer(Socket socket) throws IOException { this.socket = socket; in = new ObjectInputStream(socket.getInputStream()); out = new ObjectOutputStream(socket.getOutputStream()); Thread read = new Thread(){ public void run(){ while(true){ try{ Object obj = in.readObject(); messages.put(obj); } catch(IOException e){ e.printStackTrace(); } } } }; read.setDaemon(true); read.start(); } private void write(Object obj) { try{ out.writeObject(obj); } catch(IOException e){ e.printStackTrace(); } } } public void send(Object obj) { server.write(obj); } } 

服务器套接字中没有方法可以向所有正在运行的clinet线程发送数据或消息。 请ServerThread.java调用sendToAll usng服务器的ServerThread.java程序。

 // ... and have the server send it to all clients server.sendToAll( message ); 

查看zeroMQ。 有一些称为“pub sub”或“publish subscribe”的方法可以满足您的需求。 您还可以使用它在线程之间进行通信。 在我看来,这是一个了不起的图书馆。 它有java或jzmq绑定以及超过30多个其他绑定,所以你应该能够在你的程序中使用它。

http://www.zeromq.org/