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);
}
}