简单的java聊天服务器,只向其他客户端而不是发送者广播

简单的java聊天服务器,只向其他客户端而不是发送者广播,java,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.So

我一直在学习一个简单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<String> names = new HashSet<String>();


// Creates writers
private static HashSet<PrintWriter> writers = new HashSet<PrintWriter>();

// 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) {
            }
        }
    }
}
}
公共类聊天服务器{
//服务器侦听的端口。
专用静态最终int端口=9001;
//创建名称
私有静态HashSet name=新HashSet();
//创造作家
私有静态HashMap writers=newhashmap();
//Main方法,它只侦听端口并生成处理程序线程。
公共静态void main(字符串[]args)引发异常{
System.out.println(“聊天服务器正在运行”);
ServerSocket侦听器=新的ServerSocket(端口);
试一试{
while(true){
新处理程序(listener.accept()).start();
}
}最后{
listener.close();
}
}
私有静态类处理程序扩展线程{
私有字符串名称;
专用插座;
中的私有缓冲区读取器;
私人打印输出;
公共处理程序(套接字){
this.socket=socket;
}
公开募捐{
试一试{
//为套接字创建字符流。
in=新的BufferedReader(新的InputStreamReader(
getInputStream());
out=新的PrintWriter(socket.getOutputStream(),true);
字符串keyForEachUser=socket.getInetAddress().toString();
//从该客户端请求名称。继续请求,直到
//提交的名称尚未使用。请注意
//检查名称是否存在并添加名称
//必须在锁定名称集时执行。
while(true){
out.println(“提交名称”);
name=in.readLine();
if(name==null){
返回;
}
已同步(名称){
如果(!names.contains(name)){
名称。添加(名称);
打破
}
}
}
//现在已经选择了一个成功的名称,添加
//socket的打印写入程序到所有写入程序的集合,因此
//此客户端可以接收广播消息。
out.println(“接受名称”);
writers.put(keyForEachUser,out);
//接受来自此客户端的消息并广播它们。
//忽略无法广播到的其他客户端。
while(true){
字符串输入=in.readLine();
如果(输入==null){
返回;
}
//在何处添加阻止发送到原始发件人的部分?
for(字符串键:writers.keySet()){
if(key.equalsIgnoreCase(keyForEachUser)){
//原始用户未发送数据
}否则{
PrintWriter=writers.get(key);//获取正确的输出流
writer.println(“消息“+name+”:“+input”);
System.out.println(writer);
System.out.println(“消息”+name+:“+input”);
}
}
}
}捕获(IOE异常){
系统输出打印ln(e);
}最后{
//此客户端正在关闭!请删除其名称和打印内容
//从集合中选择writer,然后关闭其套接字。
if(name!=null){
姓名。删除(姓名);
}
if(out!=null){
删除(出);
}
试一试{
socket.close();
}捕获(IOE异常){
}
}
}
}
} 
我对您的程序做了一些更改,您以前的代码的问题是您无法识别连接的用户。现在,我用一个hashmap对象来存储PrintWriter,我在hashmap中使用的键是users inetaddress,这在pc之间是唯一的。也许你应该试试这个{ //服务器侦听的端口。 专用静态最终int端口=9001; //创建名称 私有静态HashSet name=新HashSet(); //创造作家 私有静态HashMap writers=newhashmap(); //Main方法,它只侦听端口并生成处理程序线程。 公共静态void main(字符串[]args)引发异常{ System.out.println(“聊天服务器正在运行”); ServerSocket侦听器=新的ServerSocket(端口); 试一试{ while(true){ 新处理程序(listener.accept()).start(); } }最后{ listener.close(); } } 私有静态类处理程序扩展线程{ 私有字符串名称; 专用插座; 中的私有缓冲区读取器; 私人打印输出; 公共处理程序(套接字){ this.socket=socket; } 公开募捐{ 试一试{ //为套接字创建字符流。 in=新的BufferedReader(新的InputStreamReader( getInputStream()); out=新的PrintWriter(socket.getOutputStream(),true); 字符串keyForEachUser=socket.getInetAddress().toString(); //从该客户端请求名称。继续请求,直到 //提交的名称尚未使用。请注意 //检查名称是否存在并添加名称 //必须在锁定名称集时执行。 while(true){ out.println(“提交名称”); name=in.readLine(); if(name==null){ 返回; } 已同步(名称){ 如果(!names.contains(name)){ 名称。添加(名称); 打破
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<String> names = new HashSet<String>();


// Creates writers
private static HashMap<String,PrintWriter> writers = new HashMap<String,PrintWriter>();

// 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) {
            }
        }
    }
}

}