0
서버 - 클라이언트 연결이 작동하고 클라이언트 수가 많아서 채팅에 연결하고 서로 메시지를 보낼 때 문제가 있습니다. 그러나 누군가가 오른쪽 상단의 X를 클릭하여 GUI를 종료하면 모든 것이 ****이되어 향후 참여하는 클라이언트는 아무 것도 할 수 없습니다. GUI에서 X를 누를 때 이후 클라이언트에서 Java 채팅이 작동을 멈 춥니 다.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
public class ChatC extends JFrame {
//Attributes
private JTextArea msgArea = new JTextArea();
private JTextField input = new JTextField(45);
private JTextArea onlineUsers;
private ArrayList<String> clientNames;
private String clientName = null;
private ObjectOutputStream out;
private Socket client;
/**
* ChatC constructor
* Creates an interactive GUI for the user
* Establishes connection with the server
*/
public ChatC() {
clientName = JOptionPane.showInputDialog("Enter username:");
if (clientName == null || clientName.equals("")) clientName = "Guest" +
(int) (Math.random() * 200);
setSize(600, 600);
setLocationRelativeTo(null);
setTitle("Welcome to Connect Four chat room, " + clientName);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLayout(new BorderLayout());
JButton sendMsg = new JButton("ENTER");
getRootPane().setDefaultButton(sendMsg);
msgArea.setEditable(false);
JPanel south = new JPanel(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(msgArea);
add(scrollPane, BorderLayout.CENTER);
onlineUsers = new JTextArea();
onlineUsers.setEditable(false);
add(onlineUsers, BorderLayout.EAST);
south.add(input, BorderLayout.WEST);
south.add(sendMsg, BorderLayout.EAST);
add(south, BorderLayout.SOUTH);
JMenu menu = new JMenu("Menu");
JMenuItem exit = new JMenuItem("Logout");
menu.add(exit);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
setJMenuBar(menuBar);
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
JOptionPane.showMessageDialog(null, "Thanks for playing Connect Four!", "Farewell", JOptionPane.INFORMATION_MESSAGE);
try{
out.writeObject("////" + clientName);
out.flush();
}
catch (IOException e1) {}
}//end of actionPerformed()
});//end of anonymous ActionListener
setVisible(true);
try{
client = new Socket("localhost", 16789);
out = new ObjectOutputStream(client.getOutputStream());
out.writeObject(clientName);
sendMsg.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
if (input.getText() != null && !input.getText().equals("")) {
try{
out.writeObject(input.getText());
out.flush();
}//end of try
catch (IOException ioe){}
input.setText(null);
}//end of if
}//end of actionPerformed()
});//end of anonymous ActionListener
}//end of try
catch (UnknownHostException uhe){}
catch (IOException ioe) {}
ChatCInner chatInner = new ChatCInner(client);
chatInner.start();
}//end of ChatC()
/**
* Main method
* @param args Project arguments array
*/
public static void main(String[] args) {
new ChatC();
}
/**
* Method that displays names of users that are currently participating in the chat room
*/
protected void setOnlineUsers(){
onlineUsers.setText("Users Online: \n");
for (Object o : clientNames) {
onlineUsers.append(o + "\n");
}//end of for each
}//end of setOnlineUsers()
/**
* Inner class that functions as a thread for each client
* Handles user's actions on the GUI and communication with the server
*/
private class ChatCInner extends Thread {
//Attributes
Object obj;
ObjectInputStream in;
Socket clientC;
/**
* ChatCInner constructor
* @param cl Client socket
*/
public ChatCInner(Socket cl){
clientC = cl;
}//end of ChatCInner()
/**
* Method that defines what each thread does
* Handles client interaction(sending messages etc.)
*/
public void run() {
try{
in = new ObjectInputStream(clientC.getInputStream());
while ((obj = in.readObject()) != null) {
if (obj instanceof String) {
msgArea.append((String) obj);
msgArea.setCaretPosition(msgArea.getDocument().getLength());
}//end of if
if (obj instanceof ArrayList) {
clientNames = (ArrayList<String>) obj;
if ((clientNames.indexOf(clientName) == -1)) {
client.close();
System.exit(1);
}//end of if
else setOnlineUsers();
}//end of if
}//end of while loop
}//end of try
catch (NullPointerException npe) {}
catch (IOException ioe) {
JOptionPane.showMessageDialog(null, "Server was shut down... leaving chat room.", "Server malfunctioning",JOptionPane.WARNING_MESSAGE);
System.exit(1);
}
catch (ClassNotFoundException cnfe) {}
}//end of run()
}//end of ChatInner class
}//end of ChatC class
이
클라이언트import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.ArrayList;
import java.util.Vector;
public class ChatS extends JFrame {
//Attributes
private ArrayList<String> clientNames = new ArrayList<>();
private Vector<ObjectOutputStream> outList = new Vector<>();
private Socket client = null;
/**
* ChatS constructor
* Build simple GUI with a button to terminate server
* Establishes connection with clients
*/
public ChatS() {
setTitle("Server Operational");
setSize(300, 150);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new GridLayout(0, 1));
JButton stopServer = new JButton("Terminate Server");
try{
ServerSocket server = new ServerSocket(16789);
JLabel localhost = new JLabel(InetAddress.getLocalHost().toString());
JLabel hostName = new JLabel(InetAddress.getByName("localhost").toString());
add(localhost);
add(hostName);
stopServer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}//end of actionPerformed()
});
add(stopServer);
setVisible(true);
while (true) {
client = server.accept();
ChatSInner st = new ChatSInner(client);
st.start();
}//end of while loop
}//end of try
catch(IOException ioe){}
}//end of ChatS()
/**
* Main method
* @param args Project arguments array
*/
public static void main(String[] args){ new ChatS(); }
/**
* Inner class that functions as a thread
* Handles user interaction on the chat
*/
public class ChatSInner extends Thread {
//Attributes
private int index;
private ObjectInputStream in;
private ObjectOutputStream out;
private Socket clientInner;
/**
* ChatSInner constructor
* Handles clients as separate threads
* @param cl Socket of the client
*/
public ChatSInner(Socket cl){
try {
clientInner = cl;
in = new ObjectInputStream(clientInner.getInputStream());
out = new ObjectOutputStream(clientInner.getOutputStream());
outList.add(out);
}//end of try
catch(IOException ioe){}
}//end of ChatSInner()
/**
* Method to broadcasts message to all clients connected to chat
* @param msg Message that a client is sharing with everyone
*/
protected void sendMsg(String msg){
try {
for (ObjectOutputStream out2 : outList){
out2.writeObject(msg + "\n");
out2.reset();
}//end of for each
}//end of try
catch(IOException ioe){}
}//end of sendMsg()
/**
* Method that sends ArrayList of online users back to each client
*/
protected void sendArrayList(){
try{
for (ObjectOutputStream out2 : outList) {
out2.writeObject(clientNames);
out2.reset();
}//end of for each
}//end of try
catch(IOException ioe){}
}//end of sendArrayList()
/**
* Method that defines what each thread does
* Handles client interaction in the chat room (sending messages etc.)
*/
public void run() {
String clientName;
try{
Object obj;
clientName = (String) in.readObject();
clientNames.add(clientName);
index = clientNames.indexOf(clientName);
sendMsg(clientName + " has entered the chat room.\n");
sendArrayList();
while ((obj = in.readObject()) != null){
if (obj instanceof String) {
if ((((String) obj).length() > 4) && ((String) obj).substring(0, 4).equals("////")){
sendMsg(clientNames.get(index) + " has logged out of the chat room.\n");
clientNames.remove(clientName);
sendArrayList();
} //end of if
else sendMsg(clientName + ": " + obj);
}//end of if
}//end of while loop
} //end of try
catch(IOException ioe){}
catch(ClassNotFoundException cnfe) {}
}//end of run()
}//end of ChatSInner class
}//end of ChatS class
이 서버
나는 또한 클라이언트가 연결되어있는 경우 클라이언트가 항상 가까운 메시지'out.writeObject를 보낼 수 없기 때문에 당신이 확인하는 방법을 다시 생각 제안 ("////"+ clientName);', 특히 클라이언트가 강제 종료 된 경우 또는 i f 네트워크 연결이 끊어졌습니다. – sorifiend
감사합니다. 도움이되었습니다. :) 기본 닫기 작업 대신 창 닫기를위한 창 수신기를 설정했습니다. –