向特定客户端线程发送消息

时间:2015-04-07 13:05:54

标签: java sockets server

我有这个Server类,

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;
        }
    }
}

和Thread Class,

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个客户端发送消息。

我该怎么做?

1 个答案:

答案 0 :(得分:0)

对于您的服务器类,我会更改您的ArrayList&lt;字符串&gt;等待和播放到ArrayList&lt; EchoThread&gt;。这样,您的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。