简单的Java聊天服务器,只向其他客户端而不是发件人广播

我一直在编写一个简单的Java聊天服务器的教程,并希望修改它,以便它不回显给原始发件人。 我试图用我有限的技能修改它,但我知道没有任何工作,任何帮助将不胜感激。

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.HashSet; public class ChatServer { // Port that the server listens on. private static final int PORT = 9001; // Creates names private static HashSet names = new HashSet(); // Creates writers private static HashSet writers = new HashSet(); // Main method, which just listens on a port and spawns handler threads. public static void main(String[] args) throws Exception { System.out.println("The Chatty server is running."); ServerSocket listener = new ServerSocket(PORT); try { while (true) { new Handler(listener.accept()).start(); } } finally { listener.close(); } } private static class Handler extends Thread { private String name; private Socket socket; private BufferedReader in; private PrintWriter out; public Handler(Socket socket) { this.socket = socket; } public void run() { try { // Create character streams for the socket. in = new BufferedReader(new InputStreamReader( socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); // Request a name from this client. Keep requesting until // a name is submitted that is not already used. Note that // checking for the existence of a name and adding the name // must be done while locking the set of names. while (true) { out.println("SUBMITNAME"); name = in.readLine(); if (name == null) { return; } synchronized (names) { if (!names.contains(name)) { names.add(name); break; } } } // Now that a successful name has been chosen, add the // socket's print writer to the set of all writers so // this client can receive broadcast messages. out.println("NAMEACCEPTED"); writers.add(out); // Accept messages from this client and broadcast them. // Ignore other clients that cannot be broadcasted to. while (true) { String input = in.readLine(); if (input == null) { return; } // Where to add the section that prevents sending to original sender? for (PrintWriter writer : writers) { writer.println("MESSAGE " + name + ": " + input); System.out.println(writer); System.out.println("MESSAGE " + name + ": " + input); } } } catch (IOException e) { System.out.println(e); } finally { // This client is going down! Remove its name and its print // writer from the sets, and close its socket. if (name != null) { names.remove(name); } if (out != null) { writers.remove(out); } try { socket.close(); } catch (IOException e) { } } } } } 

这是客户

 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class ChatClient { BufferedReader in; PrintWriter out; JFrame frame = new JFrame("Chatty"); JTextField textField = new JTextField(40); JTextArea messageArea = new JTextArea(8, 40); public ChatClient() { // Layout GUI textField.setEditable(false); messageArea.setEditable(false); frame.getContentPane().add(textField, "North"); frame.getContentPane().add(new JScrollPane(messageArea), "Center"); frame.pack(); // Add Listeners textField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { out.println(textField.getText()); textField.setText(""); } }); } // Prompt for and return the desired screen name. private String getName() { return JOptionPane.showInputDialog( frame, "Choose a screen name:", "Screen name selection", JOptionPane.PLAIN_MESSAGE); } // Connects to the server then enters the processing loop. private void run() throws IOException { // Make connection and initialize streams String serverAddress = "0"; Socket socket = new Socket(serverAddress, 9001); in = new BufferedReader(new InputStreamReader( socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); // Process all messages from server, according to the protocol. while (true) { String line = in.readLine(); if (line.startsWith("SUBMITNAME")) { out.println(getName()); } else if (line.startsWith("NAMEACCEPTED")) { textField.setEditable(true); } else if (line.startsWith("MESSAGE")) { messageArea.append(line.substring(8) + "\n"); } } } // Runs the client as an application with a closeable frame. public static void main(String[] args) throws Exception { ChatClient client = new ChatClient(); client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); client.frame.setVisible(true); client.run(); } } 

 public class ChatServer { // Port that the server listens on. private static final int PORT = 9001; // Creates names private static HashSet names = new HashSet(); // Creates writers private static HashMap writers = new HashMap(); // Main method, which just listens on a port and spawns handler threads. public static void main(String[] args) throws Exception { System.out.println("The Chatty server is running."); ServerSocket listener = new ServerSocket(PORT); try { while (true) { new Handler(listener.accept()).start(); } } finally { listener.close(); } } private static class Handler extends Thread { private String name; private Socket socket; private BufferedReader in; private PrintWriter out; public Handler(Socket socket) { this.socket = socket; } public void run() { try { // Create character streams for the socket. in = new BufferedReader(new InputStreamReader( socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); String keyForEachUser = socket.getInetAddress().toString(); // Request a name from this client. Keep requesting until // a name is submitted that is not already used. Note that // checking for the existence of a name and adding the name // must be done while locking the set of names. while (true) { out.println("SUBMITNAME"); name = in.readLine(); if (name == null) { return; } synchronized (names) { if (!names.contains(name)) { names.add(name); break; } } } // Now that a successful name has been chosen, add the // socket's print writer to the set of all writers so // this client can receive broadcast messages. out.println("NAMEACCEPTED"); writers.put(keyForEachUser,out); // Accept messages from this client and broadcast them. // Ignore other clients that cannot be broadcasted to. while (true) { String input = in.readLine(); if (input == null) { return; } // Where to add the section that prevents sending to original sender? for (String key : writers.keySet()) { if (key.equalsIgnoreCase(keyForEachUser)) { //original user founf not sending the data }else{ PrintWriter writer = writers.get(key); //getting the correct output stream writer.println("MESSAGE " + name + ": " + input); System.out.println(writer); System.out.println("MESSAGE " + name + ": " + input); } } } } catch (IOException e) { System.out.println(e); } finally { // This client is going down! Remove its name and its print // writer from the sets, and close its socket. if (name != null) { names.remove(name); } if (out != null) { writers.remove(out); } try { socket.close(); } catch (IOException e) { } } } } } 

我对您的程序进行了一些更改,您之前的代码问题是您无法识别连接的用户。 现在我使用hashmap对象来存储printwriters,而在hashmap中使用的键是用户inetaddress,它在pc到pc中是唯一的。 也许你应该尝试这个