客户端断开连接后停止线程

时间:2018-08-16 11:28:37

标签: java multithreading sockets

我遇到了一个问题,即当该用户断开连接时,用于从客户端获取信息的线程将不会关闭。 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) {

            }
        }
    }

}

0 个答案:

没有答案