Java 聊天应用程序:创建新套接字时会冻结

Java 聊天应用程序:创建新套接字时会冻结,java,Java,我创建了一个简短的java聊天应用程序。3类:GUI、服务器和客户端 gui有自己的getter,以便其他类的对象与它们进行通信 当我尝试创建套接字时,它首先弹出防火墙,说它阻止了一个应用程序尝试打开我计算机中的端口,好吧,我点击了“允许应用程序”,我甚至明确地将它放在防火墙允许应用程序的列表中。现在的问题是,当我点击菜单创建套接字时,它会完全冻结应用程序,你只能中止它 当然,这个应用程序是基于线程的,每当我想创建一个套接字时,比如当我点击菜单项时 if(ae.getSource() == se

我创建了一个简短的java聊天应用程序。3类:GUI、服务器和客户端

gui有自己的getter,以便其他类的对象与它们进行通信

当我尝试创建套接字时,它首先弹出防火墙,说它阻止了一个应用程序尝试打开我计算机中的端口,好吧,我点击了“允许应用程序”,我甚至明确地将它放在防火墙允许应用程序的列表中。现在的问题是,当我点击菜单创建套接字时,它会完全冻结应用程序,你只能中止它

当然,这个应用程序是基于线程的,每当我想创建一个套接字时,比如当我点击菜单项时

if(ae.getSource() == servertalkstogui.getCreate()){
然后,它启动一个以其run方法运行的线程。但在那一点上,它冻结了。我不知道我是在一个无限循环还是什么。另外,我不喜欢在循环中使用“sleep”,但到目前为止我还不知道还有其他选择,但最重要的是检测冻结应用程序的bug

package backend;

import frontend.Gui;
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.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Alvarito
 */
public class Server implements ActionListener, Runnable {

    private ServerSocket ss;
    private Socket s;
    private ObjectOutputStream oos;
    private ObjectInputStream ois;
    private Gui servertalkstogui;

    public Server(Gui in) {
        servertalkstogui = in;

    }

    @Override
    public void actionPerformed(ActionEvent ae) {

        if (ae.getSource() == servertalkstogui.getCreate()) {
            servertalkstogui.getAreachat().append("hola");
            System.out.println("creado");
            Thread t = new Thread(this);
            t.run();
        }

        if (ae.getSource() == servertalkstogui.getButton()) {
            String linea = servertalkstogui.getTextField().getText();
            writeLine(linea);
        }
    }

    @Override
    public void run() {

        try {

            ss = new ServerSocket(9999);
            s = ss.accept();
            oos = new ObjectOutputStream(s.getOutputStream());
            ois = new ObjectInputStream(s.getInputStream());

        }
        catch (IOException e) {
            try {
                this.closeServer();

            }
            catch (IOException ex) {

                System.out.println("se jodio");
                Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            }

            e.getLocalizedMessage();

        }

    }

    public void writeLine(String linea) {

        try {
            oos.writeObject(linea);
            servertalkstogui.getAreachat().append(linea);
        }
        catch (IOException e) {
            e.getLocalizedMessage();
        }

    }

    public void readLine() throws InterruptedException {
        try {
            while (true) {
                Object aux = ois.readObject();
                if (aux != null && aux instanceof String) {
                    servertalkstogui.getAreachat().append((String) aux);
                }
            }

        }
        catch (IOException | ClassNotFoundException e) {

        }

    }

    public void closeServer() throws IOException {

        try {
            oos.close();
            s.close();
            ss.close();
        }
        catch (Exception e) {
            e.addSuppressed(e);
        }
    }
}
现在是客户机类

package backend;

import frontend.Gui;
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.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Alvarito
 */
public class Client implements ActionListener, Runnable {

    private Socket s;
    private ObjectOutputStream oos;
    private ObjectInputStream ois;
    private Gui clienttalkstogui;

    public Client(Gui in) {

        clienttalkstogui = in;

    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        if (ae.getSource() == clienttalkstogui.getConnect()) {

            Thread t = new Thread(this);
            t.run();
            clienttalkstogui.getAreachat().append("me he conectado");
            System.out.println("hola");
        }
    }

    public void writeLine(String linea) {

        try {
            oos.writeObject(linea);
            clienttalkstogui.getAreachat().append(linea);
        }
        catch (IOException e) {
            e.getLocalizedMessage();
        }

    }

    public void readLine() throws InterruptedException {
        try {
            while (true) {
                Object aux = ois.readObject();
                if (aux != null && aux instanceof String) {
                    clienttalkstogui.getAreachat().append((String) aux);
                }
            }
        }
        catch (IOException | ClassNotFoundException e) {
        }
    }

    public void run() {
        try {
            s = new Socket("localhost", 9999);
            oos = new ObjectOutputStream(s.getOutputStream());
            ois = new ObjectInputStream(s.getInputStream());
        }
        catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void close() {
        try {
            ois.close();
            oos.close();
            s.close();
        }
        catch (Exception e) {
            e.getLocalizedMessage();
        }
    }
}
现在是Gui类:

package frontend;

import backend.Client;
import backend.Server;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 *
 * @author Alvarito
 */
public class Gui extends JFrame {

    private JMenuBar bar;
    private JMenu menu;
    private JMenuItem connect, create, exit;

    private JTextArea areachat;
    private JTextField campochat;
    private JButton botonchat;
    private JScrollPane scroll;

    /* WE CREATE INSTANTIATED OBJECTS OF CLASSES INTERACTING WITH THE GUI */
    Server servidor = new Server(this);
    Client cliente = new Client(this);

    /* CREATING THE CONSTRUCTOR */

    public Gui() {

        super("CHAT WINDOW");
        this.setSize(400, 500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        /* INSTANTIATE THE OBJECTS */
        bar = new JMenuBar();
        menu = new JMenu("Menu");
        connect = new JMenuItem("Conectar");
        create = new JMenuItem("Crear");
        exit = new JMenuItem("Salir");

        areachat = new JTextArea();
        campochat = new JTextField(20);
        botonchat = new JButton("Send");
        scroll = new JScrollPane(areachat);

        /* THE BAR IS PLACED IN THE JFRAME WINDOW */
        this.setJMenuBar(bar);
        /* THE MENU IS ADDED TO THE BAR */
        bar.add(menu);

        /* THE ITEMS ARE ADDED TO THE MENU */
        menu.add(connect);
        menu.add(create);
        menu.add(exit);

        /* MAKE ITEMS LISTEN TO THE EVENT FROM THE CODE CLASSES */
        create.addActionListener(servidor);
        connect.addActionListener(cliente);

        exit.addActionListener(servidor);
        exit.addActionListener(cliente);

        botonchat.addActionListener(cliente);
        botonchat.addActionListener(servidor);

        /* CREATING THE LAYOUTS */
        /* AREACHAT */
        this.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;

        gbc.gridwidth = 2;
        gbc.gridheight = 1;

        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 1;
        gbc.weighty = 1;

        this.add(scroll, gbc);

        /* TEXTFIELD */

        gbc.gridx = 0;
        gbc.gridy = 1;

        gbc.gridwidth = 1;
        gbc.gridheight = 1;

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1;
        gbc.weighty = 0;
        this.add(campochat, gbc);

        /* BOTON */

        gbc.gridx = 1;
        gbc.gridy = 1;

        gbc.gridwidth = 1;
        gbc.gridheight = 1;

        gbc.weightx = 0;
        gbc.weighty = 0;

        this.add(botonchat, gbc);

        this.setVisible(true);

    }

    /* CREATING THE GETTERS AND SETTERS */

    /* GETTERS */
    public JTextArea getAreachat() {

        return areachat;
    }

    public JMenuItem getCreate() {

        return create;
    }

    public JMenuItem getConnect() {

        return connect;

    }

    public JTextField getTextField() {

        return campochat;
    }

    public JButton getButton() {

        return botonchat;

    }

    /* SETTERS */

    public static void main(String [] args) {

        Gui objeto = new Gui();
    }

}
为了启动线程,应该使用start()而不是run()


调用run()只需调用run方法,无需启动线程。然后在ui线程中阻塞

听起来您需要熟悉调试器。或者添加一些日志记录,以便您可以查看程序内部的情况。是的,这是真的,但我不知道如何使用调试器,不使用调试器很难进行开发。哦,天哪!我不敢相信我犯了那个错误!非常感谢。