无法从多线程Java聊天室退出用户

时间:2019-06-24 17:46:40

标签: java multithreading chatroom

我一直在遵循有关创建基于GUI的聊天室的教程,该聊天室使用多线程。我想添加一个关键字,例如“ \ EXIT”,以便当用户键入该关键字时,他们将与聊天室断开连接,并向聊天室发送一条消息,指出该用户已离开。例如:

本:嗨

凯蒂:你好

Ben G2G

退出

Ben离开了聊天室

到目前为止,我有这个:

Server.java

//ChatServer.java

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.net.Socket;

public class ChatServer {

static ArrayList<String> userNames = new ArrayList<String>();

static ArrayList<PrintWriter> printWriters = new ArrayList<PrintWriter>();

public static void main(String[] args) throws Exception{

    System.out.println("Press 1 for Console or 2 for GUI");
    System.out.println("Waiting for clients..."); 

    ServerSocket ss = new ServerSocket(14001);

    while (true){

        Socket soc = ss.accept();
        System.out.println("Connection established");

        ConversationHandler handler = new ConversationHandler(soc);

        handler.start();

    }

}

}

class ConversationHandler extends Thread

{

Socket socket;
BufferedReader in;
PrintWriter out;
String name;
PrintWriter pw;
static FileWriter fw;
static BufferedWriter bw;

public ConversationHandler(Socket socket) throws IOException {

    this.socket = socket;

    fw = new FileWriter("C:\\Users\\Abhay\\Desktop\\ChatServer-Logs.txt",true);
    bw = new BufferedWriter(fw);
    pw = new PrintWriter(bw,true);

}

public void run() {

    try {

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

        int count = 0;

        while (true){

            if(count > 0){

                out.println("NAMEALREADYEXISTS");

            }

            else{

                out.println("NAMEREQUIRED");

            }

            name = in.readLine();

            if (name == null){

                return;

            }

            if (!ChatServer.userNames.contains(name)){

                ChatServer.userNames.add(name);

                break;

            }

            count++;

        }

        out.println("NAMEACCEPTED"+name);
        ChatServer.printWriters.add(out);

        while (true){

            String message = in.readLine();



            if (message.equals("EXIT")) {

                pw.println(name + " has disconnected from the chat");

                System.out.println(name + " has disconnected from the chat");

                ChatServer.userNames.remove(name);
            }

            pw.println(name + ": " + message);

            for (PrintWriter writer : ChatServer.printWriters) {

                writer.println(name + ": " + message);

            }

        }

    }

    catch (Exception e){

        System.out.println(e);

    }

}

}

Client.Java

//ChatClient.java

import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;



public class ChatClient {

static JFrame chatWindow = new JFrame("Chat Application");
static JTextArea chatArea = new JTextArea(22, 40);
static JTextField textField = new JTextField(40);
static JLabel blankLabel = new JLabel("           ");
static JButton sendButton = new JButton("Send");
static BufferedReader in;
static PrintWriter out;
static JLabel nameLabel = new JLabel("         ");

ChatClient() {

    chatWindow.setLayout(new FlowLayout());
    chatWindow.add(nameLabel);
    chatWindow.add(new JScrollPane(chatArea));
    chatWindow.add(blankLabel);
    chatWindow.add(textField);
    chatWindow.add(sendButton);
    chatWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    chatWindow.setSize(475, 500);
    chatWindow.setVisible(true);
    textField.setEditable(false);
    chatArea.setEditable(false);
    sendButton.addActionListener(new Listener());
    textField.addActionListener(new Listener());

}

void startChat() throws Exception {

    String ipAddress = JOptionPane.showInputDialog(

            chatWindow,

            "Enter IP Address:",

            "IP Address is Required!",

            JOptionPane.PLAIN_MESSAGE);  

    Socket soc = new Socket(ipAddress, 14001);

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

    while (true){

        String str = in.readLine();

        if (str.equals("NAMEREQUIRED")){

            String name = JOptionPane.showInputDialog(

                    chatWindow,

                    "Enter a unique name:",

                    "Name Required!!",

                    JOptionPane.PLAIN_MESSAGE);

            out.println(name);

        }

        else if(str.equals("NAMEALREADYEXISTS")){

            String name = JOptionPane.showInputDialog(

                    chatWindow,

                    "Enter another name:",

                    "Name Already Exits!!",

                    JOptionPane.WARNING_MESSAGE);

            out.println(name);

        }

        else if (str.startsWith("NAMEACCEPTED")){

            textField.setEditable(true);

            nameLabel.setText("You are logged in as: "+str.substring(12));

        }

        else{

            chatArea.append(str + "\n");

        }

    }

}

public static void main(String[] args) throws Exception {

    ChatClient client = new ChatClient();

    client.startChat();

}

}

class Listener implements ActionListener

{
@Override

public void actionPerformed(ActionEvent e) {

    // TODO Auto-generated method stub

    ChatClient.out.println(ChatClient.textField.getText());

    ChatClient.textField.setText("");

}

}

如您所见,在Server.java中,我使用了此IF语句。

if (message.equals("EXIT")) {

            pw.println(name + " has disconnected from the chat");

            System.out.println(name + " has disconnected from the chat");

            ChatServer.userNames.remove(name);
        }

但是,当我运行该程序时,不会将用户从聊天中删除。感谢任何帮助提示!

1 个答案:

答案 0 :(得分:1)

未在GUI上打印,因为您使用错误的PrintWriter

打印

out是打印到GUI的内容 pw从我所看到的内容打印到文件/控制台。

尝试

out.println(name + " has disconnected from the chat");

此外,为了使用户退出聊天并关闭聊天,您应该使用输入流try{..} catch{..} finally{..},输入流,输出流和套接字关闭服务器端的套接字连接,然后才能在其中进行检测客户端并关闭客户端GUI。