我遇到了一个问题,即当该用户断开连接时,用于从客户端获取信息的线程将不会关闭。 cpu使用率上升到100%,程序陷入无限循环。
问题出在服务器端,但我进行了搜索,发现没有办法解决此问题。我将发布整个服务器和客户端类,但我认为问题集中在Transfer
线程和SendToAll
方法周围。
服务器:
package serverSide;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server implements Runnable{
public final static int Port = 3000;
public static ServerSocket ss;
public static ArrayList<ClientInfo> Client;
public static String Message = "";
public static void main(String[] args) throws IOException {
@SuppressWarnings("unused")
Server server = new Server();
}
public Server() throws IOException{
ss = new ServerSocket(Port);
Client = new ArrayList<ClientInfo>();
new Thread(this).start();
}
public void run(){
try {
while (true){
//Accept new client
Socket s = ss.accept();
//Get client info
DataInputStream dis = new DataInputStream(s.getInputStream());
String Name = dis.readUTF();
//Give client storage
int Result = CheckClients();
if (Result == -1){
Result = Client.size();
Client.add(new ClientInfo(Name,Result,s));
} else {
Client.set(Result, new ClientInfo(Name,Result,s));
}
//Run get input
Transfer transfer = new Transfer(Client.get(Result).ClientID);
transfer.start();
}
} catch (IOException e) {
System.out.println("Connection Error");
}
}
public static void SendToAll() throws IOException{
for (int i=0;i<Client.size();i++){
DataOutputStream dos = new DataOutputStream(Client.get(i).ClientSocket.getOutputStream());
dos.writeUTF(Message);
}
Message = "";
}
public int CheckClients(){
int Result = -1;
for(int i = 0;i < Client.size() + 1;i++){
try{
if (Client.get(i) == null){
Result = i;
break;
}
} catch (IndexOutOfBoundsException e){
break;
}
}
return Result;
}
}
class Transfer extends Thread{
int ClientNumber;
public Transfer(int ClientNumber){
this.ClientNumber = ClientNumber;
}
public void run(){
while(true){
DataInputStream dis;
try {
dis = new DataInputStream(Server.Client.get(ClientNumber).ClientSocket.getInputStream());
String FromClient = dis.readUTF();
Server.Message = FromClient;
System.out.println(Server.Message);
Server.SendToAll();
} catch (IOException e) {
try {
this.join();
} catch (InterruptedException e1) {
}
break;
}
}
}
}
class ClientInfo {
public ClientInfo(String Name,int ClientID,Socket ClientSocket){
this.Name = Name;
this.ClientID = ClientID;
this.ClientSocket = ClientSocket;
}
public String Name;
public int ClientID;
public Socket ClientSocket;
}
客户:
package clientSide;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.Window.Type;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import java.awt.Font;
import javax.swing.SwingConstants;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientWindow {
private JFrame frmClient;
private JTextArea txtLog;
private JTextField txtMessage;
public String ServerAddress;
public String Name;
public String Password;
public Socket s;
public final int Port = 3000;
public static void main(String[] args,String sa,String n,String p) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ClientWindow window = new ClientWindow(sa,n,p);
window.frmClient.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public void ConnectToServer(JTextArea txtLog){
try {
s = new Socket(ServerAddress,Port);
System.out.println("Connected");
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(Name);
GetResponse gr = new GetResponse(txtLog,s);
gr.start();
} catch (UnknownHostException e) {
JOptionPane.showMessageDialog(this.frmClient,"Unable to open connection to " + ServerAddress + ". Unknown host.","Error" ,JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
} catch (IOException e) {
JOptionPane.showMessageDialog(this.frmClient,"Unable to open connection to " + ServerAddress + ". Unknown host.","Error" ,JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
}
public ClientWindow(String sa,String n,String p) throws InterruptedException {
ServerAddress = sa;
Name = n;
Password = p;
initialize();
}
private void initialize() {
frmClient = new JFrame();
frmClient.setResizable(false);
frmClient.setIconImage(Toolkit.getDefaultToolkit().getImage("C:\\Users\\joshu.DESKTOP-ECFG8JL\\workspace\\ChatSocket\\res\\icons\\Custom-Icon-Design-Flatastic-11-Connection.ico"));
frmClient.setType(Type.POPUP);
frmClient.setTitle("Connect");
frmClient.getContentPane().setBackground(new Color(15, 80, 120));
frmClient.setBounds(100, 100, 870, 650);
frmClient.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmClient.getContentPane().setLayout(null);
txtLog = new JTextArea();
txtLog.setEditable(false);
txtLog.setForeground(Color.WHITE);
txtLog.setFont(new Font("Calibri Light", Font.PLAIN, 24));
txtLog.setColumns(1);
txtLog.setBorder(new LineBorder(new Color(0, 153, 255)));
txtLog.setBackground(new Color(15, 80, 120));
txtLog.setBounds(7, 87, 845, 450);
frmClient.getContentPane().add(txtLog);
txtMessage = new JTextField();
txtMessage.setHorizontalAlignment(SwingConstants.LEFT);
txtMessage.setForeground(Color.WHITE);
txtMessage.setFont(new Font("Calibri Light", Font.PLAIN, 24));
txtMessage.setColumns(1);
txtMessage.setBorder(new LineBorder(new Color(0, 153, 255)));
txtMessage.setBackground(new Color(15, 80, 120));
txtMessage.setBounds(7, 559, 659, 40);
frmClient.getContentPane().add(txtMessage);
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
DataOutputStream dos;
try {
dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(Name + ": " + txtMessage.getText());
txtMessage.setText("");
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
btnSend.setForeground(Color.WHITE);
btnSend.setFont(new Font("Calibri Light", Font.BOLD, 25));
btnSend.setBackground(new Color(51, 153, 204));
btnSend.setBounds(676, 559, 176, 40);
Border emptyBorder = BorderFactory.createEmptyBorder();
btnSend.setBorder(emptyBorder);
frmClient.getContentPane().add(btnSend);
JPanel panel = new JPanel();
panel.setLayout(null);
panel.setBackground(new Color(51, 153, 204));
panel.setBounds(0, 0, 864, 75);
frmClient.getContentPane().add(panel);
JLabel lblIP = new JLabel("Connected to: " + ServerAddress);
lblIP.setVerticalAlignment(SwingConstants.TOP);
lblIP.setHorizontalAlignment(SwingConstants.LEFT);
lblIP.setForeground(new Color(15, 80, 120));
lblIP.setFont(new Font("Calibri Light", Font.BOLD, 40));
lblIP.setBounds(12, 12, 853, 50);
panel.add(lblIP);
ConnectToServer(txtLog);
}
}
class GetResponse extends Thread{
JTextArea txtLog;
Socket s;
public GetResponse(JTextArea txtLog,Socket s){
this.txtLog = txtLog;
this.s = s;
}
public void run(){
while(true){
try {
DataInputStream dis = new DataInputStream(s.getInputStream());
String Input = dis.readUTF();
txtLog.setText(txtLog.getText() + "\n" + Input);
} catch (IOException e) {
}
}
}
}