簡體   English   中英

發送消息到特定的客戶端線程

[英]send a message to specific client threads

我有這個服務器課程,

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Server {
    public static ArrayList<String> waiting = new ArrayList<String>();
    public static ArrayList<String> playing = new ArrayList<String>();
    public static ArrayList<Integer> score = new ArrayList<Integer>();

    public static void main(String[] args) {
        try {
            ServerSocket server = new ServerSocket(4321);
            while (true) {
                try {
                    Socket socket = server.accept();
                    new EchoThread(socket).start();
                } catch (Exception exc) {
                    exc.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void addClient(String name) {
        waiting.add(name);
    }

    public int getNumClients() {
        return waiting.size();
    }

    public String getClientName(int i) {
        return waiting.get(i);
    }

    public void play() {
        int scr = 0;
        for (int i = 0; i < 4; i++) {
            playing.add(waiting.get(0));
            score.add(scr);
            waiting.remove(0);
        }
    }

    public boolean checkIfPlaying(String name) {
        if (playing.indexOf(name) >= 0) {
            return true;
        } else {
            return false;
        }
    }
}

和線程類,

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class EchoThread extends Thread {
    protected Socket socket;

    public EchoThread(Socket clientSocket) {
        this.socket = clientSocket;
    }

    public void run() {
        Server s = new Server();
        DataInputStream in = null;
        DataOutputStream out = null;
        String line;

        try {
            in = new DataInputStream(socket.getInputStream());
            out = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e) {
            return;
        }

        while (true) {
            try {
                line = in.readLine();
                String[] prot = line.split(":");

                if (prot[0].equals("/login")) {
                    s.addClient(prot[1]);
                } else if (prot[0].equals("/waiting")) {
                    if (s.checkIfPlaying(prot[1])) {
                        out.writeBytes("Playing" + "\r\n");
                    } else {
                        if (s.getNumClients() >= 4) {
                            s.play();
                            out.writeBytes("Playing" + "\r\n");
                        } else {
                            out.writeBytes(s.getNumClients() + "\r\n");
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
        }
    }
}

如果客戶端連接到服務器,則客戶端的名稱存儲在服務器類數組中,等待。 如果等待的客戶端等於4,它將從等待的數組中刪除並將其放入正在播放的數組中。

我想使服務器向播放數組中的前4個客戶端發送消息。

我該怎么做?

對於您的服務器類,我將等待和播放的ArrayList <String>更改為ArrayList <EchoThread>。 這樣,您的Server類將跟蹤每個客戶端對象本身,而不僅僅是它們的名稱。 當實例化EchoThread對象時,我會將本地服務器對象傳遞給每個EchoThread,這樣每個對象都知道實例化它們的服務器。

服務器等級

import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Server {
    public ArrayList<EchoThread> waiting = new ArrayList<EchoThread>();
    public ArrayList<EchoThread> playing = new ArrayList<EchoThread>();
    public ArrayList<Integer> score = new ArrayList<Integer>();

    public static void main(String[] args) {
        try {
            // Instantiate a single server object that you can pass into your connected clients
            Server myServer = new Server();
            ServerSocket server = new ServerSocket(4321);
            while (true) {
                try {
                    Socket socket = server.accept();
                    // Pass myServer into Echo Thread 
                    new EchoThread(myServer, socket).start();
                } catch (Exception exc) {
                    exc.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // Have to synchronize this since multiple clients could be adding to this list at the same time
    public synchronized void addClient(EchoThread client) {
        waiting.add(client);
    }

    public int getNumClients() {
        return waiting.size();
    }

    public String getClientName(int i) {
        return waiting.get(i).getCName();
    }

    public void play() {
        int scr = 0;
        for (int i = 0; i < 4; i++) {
            EchoThread clientBeingMovedToPlaying = waiting.get(0);
            playing.add(clientBeingMovedToPlaying);
            score.add(scr);
            waiting.remove(0);

            // This will be a new method in your EchoThread class
            clientBeingMovedToPlaying.SendServerPlayingMessage();
        }
    }

    public boolean checkIfPlaying(String name) {
        boolean isPlaying = false;
        for(EchoThread client : playing) {
            if (client.getName().contentEquals(name)) {
                isPlaying = true;
                break;
            }
        }
        return isPlaying;
    }
}

對於您的Echo Thread類,我將在您的run方法類變量中創建您的變量,以便可以在整個類中使用它們

EchoThread類

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class EchoThread extends Thread {
    protected Socket socket;
    protected Server s;
    protected DataInputStream in;
    protected DataOutputStream out;
    protected String line;
    protected String clientName;

    // This way, each EchoThread object knows about the server
    public EchoThread(Server theServer, Socket clientSocket) {
        this.s = theServer;
        this.socket = clientSocket;
    }

    public void run() {
        try {
            in = new DataInputStream(socket.getInputStream());
            out = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e) {
            return;
        }

        while (true) {
            try {
                line = in.readLine();
                String[] prot = line.split(":");

                if (prot[0].equals("/login")) {
                    // Original code
                    //s.addClient(prot[1]);

                    // New code
                    clientName = prot[1];
                    s.addClient(this);
                } else if (prot[0].equals("/waiting")) {
                    if (s.checkIfPlaying(prot[1])) {
                        out.writeBytes("Playing" + "\r\n");
                    } else {
                        // You don't want multiple clients firing the play method, so you need to synchronize your server object
                        synchronized (s) {
                            if (s.getNumClients() >= 4) {
                                s.play();
                                out.writeBytes("Playing" + "\r\n");
                            } else {
                                out.writeBytes(s.getNumClients() + "\r\n");
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
        }
    }

    public String getCName() {
        return clientName;
    }

    public void SendServerPlayingMessage() {
        if (out != null) {
            // Send whatever message you want
        }
    }
}

我想這會滿足您的需求...原諒任何語法或邏輯錯誤,目前我還沒有IDE。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM