如何在存在多个客户端时如何向单个客户端发送消息

时间:2015-06-27 05:22:25

标签: java sockets server

我一直在搜索,但根本无法找到办法。问题是一个多用户聊天客户端,它工作正常。我遇到的问题是能够从一个用户向另一个用户发送消息(客户端 - 客户端),而不会将其打印给其他用户。

private static class Handler extends Thread {

    Map<String, Socket> database_UID = new HashMap<String, Socket>();

    private String name;
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;

    public int users;

    private String whisper;
    private String pass;
    private String pass_err = "Unauthorized login attempt";

    public Handler(Socket socket) {
        this.socket = socket;
    }

    public void Append(Socket socket, String name) {
        database_UID.put(name, socket);
        users++;
        System.out.println(ANSI_WHITE + "For reference, the Socket of " + name + " is: " + socket + ANSI_RESET);
        // socket.out.println("Welcome!");
    }

    public void validate(String name_1) {
        // With a given name, will validate Admin and TestBot passwords
        if (name_1.equals("Zach")) {
            out.println("What's your password, admin?");
            try {
                pass = in.readLine();
            } catch (IOException e) {
                System.out.println(e);
            }
            if (pass.equals("1234")) {
                name = ANSI_RED + "ADMIN" + ANSI_RESET + " Zach";
                Append(socket, name);
            } else {
                System.out.println(ANSI_WHITE + "Connection at " + socket.getInetAddress().getHostName() + ":" + socket.getPort() + " Has been terminated for:" + ANSI_RESET + " " + ANSI_RED
                        + pass_err + ANSI_RESET + "\n");
                Removal();
            }
        } else if (name_1.equals("Test")) {
            out.println("What's your password, TestBot?");
            try {
                pass = in.readLine();
            } catch (IOException e) {
                System.out.println(e);
            }
            if (pass.equals("tester")) {
                name = ANSI_RED + "TESTER" + ANSI_RESET + " TestBot";
                Append(socket, name);
            } else {
                System.out.println("Connection at " + socket.getInetAddress().getHostName() + ":" + socket.getPort() + " Has been terminated for:" + ANSI_RESET + " " + ANSI_RED + pass_err
                        + ANSI_RESET + "\n");
                Removal();
            }
        } else {
            Append(socket, name);
        }
    }

    public void Removal() {
        if (name != null) {
            names.remove(name);
        }
        if (out != null) {
            writers.remove(out);
        }
        try {
            socket.close();
        } catch (IOException e) {
        }
    }

    public void run() {
        try {
            System.out.println(ANSI_WHITE + "Connection received from " + socket.getInetAddress().getHostName() + ":" + socket.getPort() + ANSI_RESET);

            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);

            while (true) {
                out.println("What's your name?");
                name = in.readLine();
                if (name == null) {
                    return;
                }
                if (name.equals("Zach") || name.equals("zach")) {
                    validate("Zach");
                } else if (name.equals("Test") || name.equals("test")) {
                    validate("Test");
                }
                System.out.println(ANSI_WHITE + "Connection at " + socket.getInetAddress().getHostName() + ":" + socket.getPort() + " Has the name " + ANSI_RESET + "'" + name + "'\n");
                if (socket.getInetAddress().equals("localhost")) {
                    System.out.println(ANSI_WHITE + "Connection received locally" + ANSI_RESET);
                }
                synchronized (names) {
                    if (!names.contains(name)) {
                        names.add(name);
                        break;
                    }
                }
            }
            out.println("Your name has been accepted, " + name);
            writers.add(out);

            while (true) {
                String input = in.readLine();
                if (input == null) {
                    return;
                }
                for (PrintWriter writer : writers) {
                    // Allows the user to quit from the server whilst keeping
                    // the terminal open
                    if (input != null) {
                        writer.println("MESSAGE " + name + ": " + input);
                        if (input.equals("quit")) {
                            writer.println(ANSI_RED + "SYSTEM: " + ANSI_RESET + "USER " + name + " IS QUITING");
                            Removal();
                            // The problem is here
                        } else if (input.equals("whisper " + name)) {
                            out.println("Type the message to " + name);
                            whisper = in.readLine();
                            out.println(whisper);
                        } else if (input.equals("help")) {
                            out.println("\n\nHELP MENU\nTo QUIT: Type '" + ANSI_PURPLE + "quit" + ANSI_RESET + "'\nTo WHISPER: Type '" + ANSI_PURPLE + "whisper name_of_user" + ANSI_RESET + "'");
                        } else {
                            writer.println("MESSAGE " + name + ": " + input);
                        }
                    }
                }
            }
        } catch (IOException e) {
            System.out.println(e);
        } finally {
            // Removes the user from the list of names
            Removal();
        }
    }
}

我使用的是Thread,当用户加入时,我将他们的名字和Socket都添加到字典中

Map<String, Socket> database_UID = new HashMap<String, Socket>();

public void Append(Socket socket, String name) {
    database_UID.put(name, socket);
    users++;
    System.out.println(ANSI_WHITE+"For reference, the Socket of "+name+" is: "+socket+ANSI_RESET);
    //socket.out.println("Welcome!");
}

我想做的是,如评论中所见,socket.out.println(USER'S_MESSAGE);之类的东西,显然不起作用。 如果相关,则将客户端的套接字添加为

public Handler(Socket socket) {
    this.socket = socket;
}

tl; dr版本:

人A到整个服务器:嗨!

B人专门针对A人:嗨!

编辑:上面包含整个线程。 for(PrintWriter writer : writers) {就是它所要去的地方,在耳语之下。

1 个答案:

答案 0 :(得分:1)

请按照以下步骤操作

  1. 在服务器上创建另一个线程以收听来自客户端的消息。
  2. 从客户端A向服务器发送消息
  3. 检查目标客户端(可以是从客户端发送到服务器的消息的一部分)
  4. 将邮件从服务器发送到目标客户端。