向所有客户端发送消息(客户端 - 服务器通信) [英] Sending a message to all clients (Client - Server communication)
问题描述
所以现在,我正在制作一个基于多线程的客户端服务器应用程序。在服务器端,我为接受的单独连接创建了一个线程。
So now, I am making a client server app based multithread. In server side, I make a thread for everysingle connection that accepted.
在线程类中,我创建了一个向客户端发送命令的方法。我只想要的是,如何向所有正在运行的客户端发送参数?对于简单的声明,我只想让这个服务器向所有连接的客户端发送消息。
In thread class, I make a method that send a command to client. What i just want is, how to send a parameter to all running client? For simple statement, i just want to make this server send a message to all connected client.
我已经读过这篇文章并找到 sendToAll(String message)来自此链接的code>方法。但是当我尝试使用我的代码时,在
ServerSocket
中没有类似的方法。
I've been read this post and find sendToAll(String message)
method from this link. But when i am try in my code, there is no method like that in ServerSocket
.
好的这是我的服务器和线程的示例代码。
Okay this is my sample code for server and the thread.
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服务等。
The below answer, is not recommended for a full fledged server, as for this you should use Java EE with servlets, web services etc.
这仅适用于少数计算机想要连接以执行特定的任务,并使用简单的Java套接字不是一般问题。想想分布式计算或多人游戏。
This is only intended where a few computers want to connect to perform a specific task, and using simple Java sockets is not a general problem. Think of distributed computing or multi-player gaming.
编辑:我 - 从第一篇文章开始 - 大大更新了这个架构,现在经过测试和线程安全。任何需要它的人都可以下载这里。
I've - since first post - greatly updated this architecture, now tested and thread-safe. Anybody who needs it may download it here.
只需使用(直接或通过子类化)服务器
和客户端
,启动()
他们,一切准备就绪。阅读内联注释以获得更强大的选项。
Simply use (directly, or by subclassing) Server
and Client
, start()
them, and everything is ready. Read the inline comments for more powerful options.
虽然客户端之间的通信相当复杂,但我会尝试简化它,最有可能。
While communication between clients are fairly complicated, I'll try to simplify it, the most possible.
以下是服务器中的要点:
Here are the points, in the server:
- 保留已连接客户的列表。
- 定义线程,用于服务器输入。
- 定义收到消息的队列。
- 从队列中轮询线程并使用它。
- 一些用于发送消息的实用方法。
- Keeping a list of connected clients.
- Defining a thread, for server input.
- Defining a queue of the received messages.
- A thread polling from the queue, and work with it.
- Some utility methods for sending messages.
对于客户:
- 定义一个线程,用于客户输入。
- 定义收到消息的队列。
- 从队列中轮询线程并使用它。
这是Server类:
public class Server {
private ArrayList<ConnectionToClient> clientList;
private LinkedBlockingQueue<Object> messages;
private ServerSocket serverSocket;
public Server(int port) {
clientList = new ArrayList<ConnectionToClient>();
messages = new LinkedBlockingQueue<Object>();
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类:
And here for the Client class:
public class Client {
private ConnectionToServer server;
private LinkedBlockingQueue<Object> messages;
private Socket socket;
public Client(String IPAddress, int port) throws IOException{
socket = new Socket(IPAddress, port);
messages = new LinkedBlokingQueue<Object>();
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);
}
}
这篇关于向所有客户端发送消息(客户端 - 服务器通信)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!