[英]Sending a message to all clients (Client - Server communication)
所以現在,我正在制作一個基於多線程的客戶端服務器應用程序。 在服務器端,我為接受的單獨連接創建了一個線程。
在線程類中,我創建了一個向客戶端發送命令的方法。 我只想要的是,如何向所有正在運行的客戶端發送參數? 對於簡單的聲明,我只想讓這個服務器向所有連接的客戶端發送消息。
我已閱讀此帖並從此鏈接中找到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套接字不是一般問題。 想想分布式計算或多人游戲。
編輯:我 - 從第一篇文章 - 大大更新了這個架構,現在測試和線程安全。 任何需要它的人都可以在這里下載。
只需使用(直接或通過子類化) Server
和Client
, start()
它們,一切就緒。 閱讀內聯注釋以獲得更強大的選項。
雖然客戶之間的溝通相當復雜,但我會盡量簡化它。
以下是服務器中的要點:
對於客戶:
這是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類:
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);
}
}
服務器套接字中沒有方法可以向所有正在運行的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多個其他綁定,所以你應該能夠在你的程序中使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.