【问题标题】:Broadcast client message to all clients in a chatroom Java向聊天室 Java 中的所有客户端广播客户端消息
【发布时间】:2018-03-12 10:05:48
【问题描述】:

所以我一直在制作一个基于单个服务器的聊天室,客户可以在其中连接并在聊天室中交谈。目前,每个客户端都可以与服务器对话,服务器会返回客户端所说的内容。但我一直在努力向所有客户广播一条客户消息。

我将所有套接字连接存储在 ArrayList 中,然后创建了一个 for 循环来遍历所有连接,以向所有连接的客户端回显一条消息。不幸的是,我的代码不起作用,我不明白为什么。这是我的代码:

处理程序代码:

public class Handler implements Runnable {

private Socket client;
String message = "";

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

@Override
public void run() {
  try{  
    try{
        ChatClient CCG = new ChatClient();
        Scanner INPUT = new Scanner(client.getInputStream()); //input data from the server
        PrintWriter OUT = new PrintWriter(client.getOutputStream());  //output data from the server
        while(true){

            if(!INPUT.hasNextLine()){   //if nothings there, end it
                    return;
            }

            message = INPUT.nextLine(); //get input

            System.out.println("Client HANDLER said: "+ message);

                //echo out what the client says to all the users
            for(int i=1; i<= ChatServer.ConnectionArray.size(); i++){

                Socket TEMP_SOCK = (Socket) ChatServer.ConnectionArray.get(i-1);
                PrintWriter TEMP_OUT = new PrintWriter(TEMP_SOCK.getOutputStream());
                TEMP_OUT.println(message);
                TEMP_OUT.flush();
                System.out.println("Sent to: " + TEMP_SOCK.getLocalAddress().getHostName());    //displyed in the console
            }
        }

    }finally{
            client.close();
        }
    }catch(Exception X){
        X.printStackTrace();
    }

}

}

编辑:client.getOutputStream() 更改为 TEMP_SOCK.getOutputStream() 但仍然没有运气:/

服务器代码:

public class ChatServer {

public static ServerSocket server;
public static boolean ServerOn=true; 
public static ArrayList<Socket> ConnectionArray = new ArrayList<Socket>();  //holds all the connections so messages can be echoed to all the other users
public static ArrayList<String> CurrentUsers = new ArrayList<String>(); //current users

public static void main(String[] args){
    //ExecutorService executor = Executors.newFixedThreadPool(30);    //number of clients allowed to join the server
    try {
        server = new ServerSocket(14001);
        System.out.println("Server started!");
        System.out.println("Waiting for clients to connect...");

        while(true){

            try {
                //ChatClient chatClient = new ChatClient();
                Socket client = server.accept();
                ConnectionArray.add(client);  //add socket to connection array and allows multiple users to enter server
                System.out.println(ConnectionArray);
                //CurrentUsers.add(chatClient.user);
                //System.out.println("Current users: "+CurrentUsers);
                System.out.println("Client connected from: " + client.getLocalAddress().getHostName());   //gets their ip address and local host name
                Thread thread = new Thread(new Handler(client));
                thread.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

}

客户代码:

public class ChatClient extends javax.swing.JFrame {

Socket sock;
String message;
int port = 14001;
PrintWriter write;
BufferedReader read;
String user;
ArrayList<String> usersOnline = new ArrayList();
InputStreamReader streamreader;
boolean userConnected = false;

public ChatClient() {
    initComponents();
}

/*public class Incoming implements Runnable{
    public void run(){
        try{
            sock = new Socket("localhost",14001);
            write = new PrintWriter(out);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}*/

public void addUser(){
    onlineUsersTextArea.append(user+" \n");
    usersOnline.add(user);
    System.out.println(usersOnline);
}

/*public void Send(){
    String bye = (user + ": :Disconnect");
    try{
        write.println(bye);
        write.flush();
    }catch(Exception ex){
        chatTextArea.append("Could not send disconnect message. \n");
    }
}*/

public void userDisconnected(){
    chatTextArea.append(user + " has disconnected.\n");
}

public void Disconnect(){
    try{
        chatTextArea.append("Disconnected.\n"); // Notify user that they have disconnected
        write.flush();
        sock.close();   // Closes the socket
        System.out.println(user + " has disconnected.");
    }catch(Exception e){
        chatTextArea.append("Failure to disconnect.\n");
    }

    userConnected = false;
    onlineUsersTextArea.setText("");    // Remove name from online users
    usernameInputField.setEditable(true);   // Allows a username to be created
}

private void connectButtonActionPerformed(java.awt.event.ActionEvent evt) {                                              
    if(userConnected == false){
        user = usernameInputField.getText();
        usernameInputField.setEditable(false);

    try{
        sock = new Socket("localhost", port);
        InputStreamReader sReader = new InputStreamReader(sock.getInputStream());
        write = new PrintWriter(sock.getOutputStream());
        read = new BufferedReader(sReader);
        addUser();
        chatTextArea.append(user + " has connected. \n");
        write.println(user+" has connected.");  // Display username of client when connection is established
        write.flush();  // Flushes the stream
        userConnected = true;
    } catch (IOException ex) {
        chatTextArea.append("Failed to connect.\n");
        usernameInputField.setEditable(true);
        ex.printStackTrace();
    }
    }else if(userConnected == true){
        chatTextArea.append("You are already connected. \n");
    }
}                                             

private void disconnectButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                 
    Disconnect();
    userDisconnected();
}                                                

private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           
    String nothing = "";
    if((userInputTextArea.getText()).equals(nothing)){
        userInputTextArea.setText("");
        userInputTextArea.requestFocus();
    }else{
        try{
            chatTextArea.append(user + ": " + userInputTextArea.getText()+" \n");
            write.println(user + ": " + userInputTextArea.getText());
            write.flush();
        }catch(Exception ex){
            chatTextArea.append("Message failed to send. \n");
        }
        userInputTextArea.setText("");
        userInputTextArea.requestFocus();
    }

    userInputTextArea.setText("");
    userInputTextArea.requestFocus();
}                                          

private void usernameInputFieldActionPerformed(java.awt.event.ActionEvent evt) {                                                   
}                                                  

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new ChatClient().setVisible(true);
        }
    });
}

}

我的 for 循环Handler 类中。我不明白为什么没有将消息发送给客户。 TEMP_SOCK(临时套接字)应该可以工作(我认为),但服务器只接收消息但不回显它们。

任何有关如何解决此问题的帮助将不胜感激!谢谢你:)

【问题讨论】:

  • @YogeshBadke 我认为不同的 JVM。我先分别运行 ChatServer 类,然后分别运行 ChatClient 类。

标签: java sockets for-loop arraylist server


【解决方案1】:

PrintWriter TEMP_OUT = new PrintWriter(client.getOutputStream()); 表示你总是发送到同一个客户端,你应该使用PrintWriter TEMP_OUT = new PrintWriter(TEMP_SOCK.getOutputStream());

【讨论】:

  • 刚刚尝试了 2 个连接的客户端,但两个控制台上均未显示任何消息:/
  • 你确定不是客户端代码的错吗?你也可以发一些吗?
  • 刚刚编辑了帖子。请原谅我已经实现了 GUI 的大量代码,所以我不确定哪些方法会有所帮助。由于明显的原因,我没有显示实际的 GUI 代码 :)
  • 我看不到您从服务器读取消息的位置。你需要类似inputLine = read.readLine()
  • 我应该将代码放在我的客户端类中的什么位置?为我缺乏知识而道歉。我会将它放在 initComponents() 方法所在的公共 ChatClient 中吗?
猜你喜欢
  • 2015-07-03
  • 2016-12-02
  • 1970-01-01
  • 2019-04-01
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 2017-09-23
相关资源
最近更新 更多