Java 客户端/服务器聊天室仅与一个客户端一起工作

Java 客户端/服务器聊天室仅与一个客户端一起工作,java,swing,chat,Java,Swing,Chat,我正在创建一个聊天室,它可以与一个客户端和一个服务器配合使用,但是当第二个或第三个客户端连接时,只有第一个加入的客户端才能发送和接收消息。第二、第三等。人们不能发送或接收。代码如下: 服务器: 客户: import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.

我正在创建一个聊天室,它可以与一个客户端和一个服务器配合使用,但是当第二个或第三个客户端连接时,只有第一个加入的客户端才能发送和接收消息。第二、第三等。人们不能发送或接收。代码如下: 服务器:

客户:

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Client implements WindowListener, KeyListener, ActionListener, Runnable {
    private JButton join;
    private JButton clelog;
    private JButton send;
    private JTextField portf;
    private JTextField clientf;
    private JTextField mesf;
    private JTextArea log;
    private JFrame jfr;
    private Socket sock;
    private BufferedReader in;
    private PrintWriter out;
    private boolean closed = false;
    private Client() throws Throwable {
        jfr = new JFrame();
        jfr.setDefaultCloseOperation(3);
        jfr.setLayout(new GridLayout(3, 1));
        join = new JButton("Join");
        join.addActionListener(this);
        portf = new JTextField("Port", 7);
        clientf = new JTextField("Client", 15);
        jfr.add(portf);
        jfr.add(clientf);
        jfr.add(join);
        jfr.pack();
        jfr.setLocationRelativeTo(null);
        jfr.setVisible(true);
    }
    @Override public void actionPerformed(ActionEvent e) {
        if(e.getSource() == join)
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    join();
                }
            });
        else if(e.getSource() == send)
            send(mesf.getText());
        else if(e.getSource() == clelog)
            log.setText("");
    }
    private void join() {
        jfr.dispose();
        try {
            Integer.parseInt(portf.getText());
        }catch(NumberFormatException e2) {
            JOptionPane.showMessageDialog(jfr, "The port entered was not valid. Terminating...", "Port Not Valid", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }
            if(sock != null)
                try {
                    sock.close();
                } catch (IOException e1) {
                    reportError(e1);
                }
        try {
            runProgram();
        } catch (Throwable e1) {
            reportError(e1);
        }
    }
    private void runProgram() throws Throwable{
        JFrame rfr = new JFrame("Consle");
        rfr.setDefaultCloseOperation(0);
        rfr.addWindowListener(this);
        rfr.setLayout(new GridLayout(2, 2));
        log = new JTextArea();
        log.setEditable(false);
        rfr.add(log);
        mesf = new JTextField(20);
        clelog = new JButton("Clear Consle");
        send = new JButton("Send");
        send.addActionListener(this);
        clelog.addActionListener(this);
        rfr.add(clelog);
        JPanel pan = new JPanel();
        JPanel p = new JPanel();
        pan.add(mesf);
        p.add(send);
        rfr.add(pan);
        rfr.add(p);
        rfr.pack();
        rfr.setLocationRelativeTo(null);
        rfr.setVisible(true);
        sock = new Socket(clientf.getText(), Integer.parseInt(portf.getText()));
        out = new PrintWriter(sock.getOutputStream());
        in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
        new Thread(this).start();
    }
    @Override public void run() {
        String inp = "";
        try {
            while((inp = in.readLine()) != null) {
                if(!(inp.equals("server.exit")))
                    log.append(inp+"\n");
                else
                    closed = true;
            }
        } catch (Throwable e) {
            reportError(e);
        }
    }
    @Override public void keyTyped(KeyEvent e) {}
    @Override public void keyPressed(KeyEvent e) {}
    @Override public void keyReleased(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_ENTER) {
            send(mesf.getText());
        }
    }
    private void send(String text) {
        out.print(mesf.getText()+"\n");
        out.flush();
        mesf.setText("");
    }
    @Override public void windowOpened(WindowEvent e) {}
    @Override public void windowClosing(WindowEvent e) {
        if(closed)
            System.exit(0);
        else
            try {
                int exit = JOptionPane.showConfirmDialog(jfr, "Are you sure you want to exit?", "Are you sure?", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
                if(exit == 0) {
                    sock.close();
                    System.exit(0);
                } else
                    JOptionPane.showMessageDialog(jfr, "The exit was successfully canceled.", "Exit canceled", JOptionPane.INFORMATION_MESSAGE);
            }catch(Throwable e1) {
                reportError(e1);
            }
    }
    @Override public void windowClosed(WindowEvent e) {}
    @Override public void windowIconified(WindowEvent e) {}
    @Override public void windowDeiconified(WindowEvent e) {}
    @Override public void windowActivated(WindowEvent e) {}
    @Override public void windowDeactivated(WindowEvent e) {}
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            new Client();
        }catch(NumberFormatException e) {
            JOptionPane.showMessageDialog(null, "The port you entered is not valid. Terminating...", "Port not valid", 0);
            System.exit(0);
        }catch(Throwable e) {
            System.exit(0);
        }
    }
    protected void reportError(Throwable error) {
        if(error.getMessage() != null && error.getCause() != null)
            JOptionPane.showMessageDialog(null, "This happend because "+error.getCause()+". A deatial message has been included: "+error.getMessage()+". Terminating...", error.getClass().getName(), JOptionPane.ERROR_MESSAGE);
        else if(error.getMessage() != null && error.getCause() == null)
            JOptionPane.showMessageDialog(null, "This happend because "+error.getCause()+". No deatial message was included. Terminating...", error.getClass().getName(), JOptionPane.ERROR_MESSAGE);
        else if(error.getMessage() == null && error.getCause() != null) 
            JOptionPane.showMessageDialog(null, "It is unknown why this error occured, but a deatial message has been included: "+error.getMessage()+". Terminating...", error.getClass().getName(), JOptionPane.ERROR_MESSAGE);
        else if(error.getMessage() == null && error.getCause() == null)
            JOptionPane.showMessageDialog(null, "A "+error.getClass().getName()+" has occured. Terminating...", error.getClass().getName(), JOptionPane.ERROR_MESSAGE);
        StackTraceElement[] arr = error.getStackTrace();
        for(StackTraceElement a:arr) {
            log.append("\n"+a);
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.exit(0);
        }
        System.exit(0);
    }
}

您只有一个套接字,并且等待客户端连接到它。您没有在同一服务器上处理多个客户端的机制。试着用搜索引擎来举一些例子,看看你是如何做到这一点的“聊天室java教程”哦,所以你需要处理多个客户端?!真臭。
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Client implements WindowListener, KeyListener, ActionListener, Runnable {
    private JButton join;
    private JButton clelog;
    private JButton send;
    private JTextField portf;
    private JTextField clientf;
    private JTextField mesf;
    private JTextArea log;
    private JFrame jfr;
    private Socket sock;
    private BufferedReader in;
    private PrintWriter out;
    private boolean closed = false;
    private Client() throws Throwable {
        jfr = new JFrame();
        jfr.setDefaultCloseOperation(3);
        jfr.setLayout(new GridLayout(3, 1));
        join = new JButton("Join");
        join.addActionListener(this);
        portf = new JTextField("Port", 7);
        clientf = new JTextField("Client", 15);
        jfr.add(portf);
        jfr.add(clientf);
        jfr.add(join);
        jfr.pack();
        jfr.setLocationRelativeTo(null);
        jfr.setVisible(true);
    }
    @Override public void actionPerformed(ActionEvent e) {
        if(e.getSource() == join)
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    join();
                }
            });
        else if(e.getSource() == send)
            send(mesf.getText());
        else if(e.getSource() == clelog)
            log.setText("");
    }
    private void join() {
        jfr.dispose();
        try {
            Integer.parseInt(portf.getText());
        }catch(NumberFormatException e2) {
            JOptionPane.showMessageDialog(jfr, "The port entered was not valid. Terminating...", "Port Not Valid", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }
            if(sock != null)
                try {
                    sock.close();
                } catch (IOException e1) {
                    reportError(e1);
                }
        try {
            runProgram();
        } catch (Throwable e1) {
            reportError(e1);
        }
    }
    private void runProgram() throws Throwable{
        JFrame rfr = new JFrame("Consle");
        rfr.setDefaultCloseOperation(0);
        rfr.addWindowListener(this);
        rfr.setLayout(new GridLayout(2, 2));
        log = new JTextArea();
        log.setEditable(false);
        rfr.add(log);
        mesf = new JTextField(20);
        clelog = new JButton("Clear Consle");
        send = new JButton("Send");
        send.addActionListener(this);
        clelog.addActionListener(this);
        rfr.add(clelog);
        JPanel pan = new JPanel();
        JPanel p = new JPanel();
        pan.add(mesf);
        p.add(send);
        rfr.add(pan);
        rfr.add(p);
        rfr.pack();
        rfr.setLocationRelativeTo(null);
        rfr.setVisible(true);
        sock = new Socket(clientf.getText(), Integer.parseInt(portf.getText()));
        out = new PrintWriter(sock.getOutputStream());
        in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
        new Thread(this).start();
    }
    @Override public void run() {
        String inp = "";
        try {
            while((inp = in.readLine()) != null) {
                if(!(inp.equals("server.exit")))
                    log.append(inp+"\n");
                else
                    closed = true;
            }
        } catch (Throwable e) {
            reportError(e);
        }
    }
    @Override public void keyTyped(KeyEvent e) {}
    @Override public void keyPressed(KeyEvent e) {}
    @Override public void keyReleased(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_ENTER) {
            send(mesf.getText());
        }
    }
    private void send(String text) {
        out.print(mesf.getText()+"\n");
        out.flush();
        mesf.setText("");
    }
    @Override public void windowOpened(WindowEvent e) {}
    @Override public void windowClosing(WindowEvent e) {
        if(closed)
            System.exit(0);
        else
            try {
                int exit = JOptionPane.showConfirmDialog(jfr, "Are you sure you want to exit?", "Are you sure?", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
                if(exit == 0) {
                    sock.close();
                    System.exit(0);
                } else
                    JOptionPane.showMessageDialog(jfr, "The exit was successfully canceled.", "Exit canceled", JOptionPane.INFORMATION_MESSAGE);
            }catch(Throwable e1) {
                reportError(e1);
            }
    }
    @Override public void windowClosed(WindowEvent e) {}
    @Override public void windowIconified(WindowEvent e) {}
    @Override public void windowDeiconified(WindowEvent e) {}
    @Override public void windowActivated(WindowEvent e) {}
    @Override public void windowDeactivated(WindowEvent e) {}
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            new Client();
        }catch(NumberFormatException e) {
            JOptionPane.showMessageDialog(null, "The port you entered is not valid. Terminating...", "Port not valid", 0);
            System.exit(0);
        }catch(Throwable e) {
            System.exit(0);
        }
    }
    protected void reportError(Throwable error) {
        if(error.getMessage() != null && error.getCause() != null)
            JOptionPane.showMessageDialog(null, "This happend because "+error.getCause()+". A deatial message has been included: "+error.getMessage()+". Terminating...", error.getClass().getName(), JOptionPane.ERROR_MESSAGE);
        else if(error.getMessage() != null && error.getCause() == null)
            JOptionPane.showMessageDialog(null, "This happend because "+error.getCause()+". No deatial message was included. Terminating...", error.getClass().getName(), JOptionPane.ERROR_MESSAGE);
        else if(error.getMessage() == null && error.getCause() != null) 
            JOptionPane.showMessageDialog(null, "It is unknown why this error occured, but a deatial message has been included: "+error.getMessage()+". Terminating...", error.getClass().getName(), JOptionPane.ERROR_MESSAGE);
        else if(error.getMessage() == null && error.getCause() == null)
            JOptionPane.showMessageDialog(null, "A "+error.getClass().getName()+" has occured. Terminating...", error.getClass().getName(), JOptionPane.ERROR_MESSAGE);
        StackTraceElement[] arr = error.getStackTrace();
        for(StackTraceElement a:arr) {
            log.append("\n"+a);
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.exit(0);
        }
        System.exit(0);
    }
}