Reputation: 21
I've been searching for a while, and simply can't find a way to do this. The problem is a multi-user chat client, which works fine. The issue I'm having is being able to send a message from one user to another (client-client), without printing it to the other users.
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();
}
}
}
I'm using a Thread, and when the user joins, I add both their name and their Socket to a dictionary
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!");
}
What I would like to do is, as seen in a comment there, something like socket.out.println(USER'S_MESSAGE);
, which obviously doesn't work.
If it's relevant, the client's socket is being added as
public Handler(Socket socket) {
this.socket = socket;
}
The tl;dr version:
Person A to whole server: Hi!
Person B specifically to Person A: Hi!
EDIT: Included above is the entire Thread. The for(PrintWriter writer : writers) {
is where it would go, under 'whisper'.
Upvotes: 0
Views: 142
Reputation: 850
Follow these steps
Upvotes: 1