有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使JButton打印“连接…”试图连接到socket时发送到JTextArea的消息

我目前正在开发一个简单的聊天服务器程序,可以同时处理多个连接的客户端(创建一个基本的聊天室),我遇到了一个很小但很烦人的问题,我似乎无法解决

我有一个JButton,当单击它时,它检索用户在各自的jtext字段中输入的IP地址、端口号和名称。然后将这些值传递给socket构造函数,以尝试打开连接(名称发送到其他位置,仅标识服务器上的用户)。我试着做的是“连接…”文本区域中显示的消息,随后是成功连接报告或错误(如果抛出)。然而,在实践中——如果我故意输入一个坏的IP(强制抛出错误)——在抛出错误之前,不会向文本区域追加任何文本;i、 这是一次完成的

以下是单击按钮时运行的代码:

private void submitBtnClicked() {
        String hostName = ipJtf.getText();
        int port = Integer.parseInt(portJtf.getText());
        String name = nameJtf.getText();

        if (!name.trim().equals("")) {

            // This is where I want the code to print "Connecting..."
            jta.setText("");
            jta.append("Connecting...\n");

            try {

                socket = new Socket(hostName, port);
                jta.append("Connected to server on: " + hostName + " : " + port + "\n");

                writer = new PrintWriter(socket.getOutputStream(), true);
                writer.println(name);

                new ReadThread(socket, this).start();
                new WriteThread(socket, this).start();

            }
            catch (UnknownHostException ex) {
                jta.append("Server not found: " + ex.getMessage() + "\n");
            }
            catch (IOException e) {
                jta.append("I/O Error: " + e.getMessage() + "\n");
            }
        }
        else {
            jta.setText("");
            jta.append("Please enter a user name before connecting.\n");
        }
    }

因此,当代码运行时,它当前将附加:

Connecting...
I/O Error: Connection refused: connect

同时打印,而不是打印“连接…”首先是错误,然后是错误,当它不成功时

我是编程方案的初学者,所以我确信这只是因为我不理解一些基本的东西,或者在我的学习中还没有遇到这些东西,但是到目前为止我还没有找到解决方案。我怀疑这更多的是因为我没有弄清楚应该问什么问题,因为我确信一定有人以前有过这个问题,并且在stackoverflow上得到了很好的回答;如果是这样的话,我会非常感激有人指点我

提前感谢您在这件事上给予的一切帮助

注:我知道代码在当前状态下有点凌乱——主要是因为我在构建应用程序时测试了各种东西

复制问题的附加代码

客户。爪哇

package ChatServerV2.Client;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;

public class Client extends JFrame {

    private JTextField ipJtf = new JTextField(13);
    private JTextField portJtf = new JTextField(4);
    private JTextField nameJtf = new JTextField(15);
    private JTextField messageJtf = new JTextField();
    private JTextArea jta = new JTextArea();
    private Socket socket;

    private String hostName;
    private int port;
    private String userName;

    // IO streams will go here
    private PrintWriter writer;

    public static void main(String[] args) {
        new Client();
    }

    public Client() {
        initUi();



    }

    // Builds the client UI and sets it as visible
    private void initUi() {
        JPanel p = new JPanel();
        p.setLayout(new BorderLayout());
        p.add(new JLabel("IP and Port: "), BorderLayout.WEST);
        p.add(ipJtf, BorderLayout.CENTER);
        p.add(portJtf, BorderLayout.EAST);
        // Add jtf listeners

        JPanel p2 = new JPanel();
        p2.setLayout(new BorderLayout());
        p2.add(new JLabel("Name: "), BorderLayout.WEST);
        p2.add(nameJtf, BorderLayout.CENTER);
        // Add jtf listener

        JPanel p5 = new JPanel();
        p5.setLayout(new BorderLayout());
        JButton btn = new JButton("Submit");
        btn.addActionListener((ActionEvent e) -> {
            submitBtnClicked();
        });
        p5.add(btn, BorderLayout.EAST);

        JPanel p4 = new JPanel();
        p4.setLayout(new BorderLayout());
        p4.add(p, BorderLayout.NORTH);
        p4.add(p2, BorderLayout.SOUTH);

        JPanel p6 = new JPanel(new BorderLayout());
        // p6.setLayout(new BorderLayout());
        p6.add(p4, BorderLayout.CENTER);
        p6.add(p5, BorderLayout.EAST);

        JPanel p3 = new JPanel();
        p3.setLayout(new BorderLayout());
        p3.add(new JLabel("Message: "), BorderLayout.WEST);
        messageJtf.addActionListener((ActionEvent e) -> {
            sendingAMessage();
        });
        p3.add(messageJtf, BorderLayout.CENTER);
        // Add jtf listener

        setLayout(new BorderLayout());
        add(p6, BorderLayout.NORTH);
        add(new JScrollPane(jta), BorderLayout.CENTER);
        jta.setEditable(false);
        add(p3, BorderLayout.SOUTH);

        setTitle("Client");
        setSize(500, 300);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

    }

    /** Writes a message locally to the client's window */
    public void clientWrite(String message) {
        jta.append(message + "\n");
    }

    private void submitBtnClicked() {
        String hostName = ipJtf.getText();
        int port = Integer.parseInt(portJtf.getText());
        String name = nameJtf.getText();

        if (!name.trim().equals("")) {

            jta.setText("");
            jta.append(javax.swing.SwingUtilities.isEventDispatchThread() + "\n");
            jta.append("Connecting...\n");
            try {

                socket = new Socket(hostName, port);
                jta.append("Connected to server on: " + hostName + " : " + port + "\n");

                writer = new PrintWriter(socket.getOutputStream(), true);
                writer.println(name);

                new ReadThread(socket, this).start();
                new WriteThread(socket, this).start();

            }
            catch (UnknownHostException ex) {
                jta.append("Server not found: " + ex.getMessage() + "\n");
            }
            catch (IOException e) {
                jta.append("I/O Error: " + e.getMessage() + "\n");
            }
        }
        else {
            jta.setText("");
            jta.append("Please enter a user name before connecting.\n");
        }
    }

    private void sendingAMessage() {

    }
}

读线程。爪哇

package ChatServerV2.Client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;


public class ReadThread extends Thread {
    private BufferedReader reader;
    private Socket socket;
    private Client client;

    public ReadThread(Socket socket, Client client) {
        this.socket = socket;
        this.client = client;

        try {
            InputStream input = socket.getInputStream();
            reader = new BufferedReader(new InputStreamReader(input));
        }
        catch (IOException e) {
            client.clientWrite("Error getting input stream: " + e.getMessage());
        }
    }

    public void run() {
        while (true) {
            try {
                String response = reader.readLine();
                client.clientWrite(response);
            }
            catch (IOException e) {
                client.clientWrite("Error reading from server: " + e.getMessage());
                break;
            }
        }
    }
}

读写。爪哇

package ChatServerV2.Client;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;


public class WriteThread extends Thread {
    private PrintWriter writer;
    private Socket socket;
    private Client client;

    public WriteThread(Socket socket, Client client) {
        this.socket = socket;
        this.client = client;

        try {
            OutputStream output = socket.getOutputStream();
            writer = new PrintWriter(output);
        }
        catch (IOException e) {
            client.clientWrite("Error getting output stream: " + e.getMessage());
        }
    }

    public void run() {

    }
}

正如前面提到的,这是一个初学者正在进行的工作,所以如果它看起来很糟糕,那是因为它是


共 (1) 个答案

  1. # 1 楼答案

    要更好地演示,请参见问题(和解决方案)向ReadThread添加延迟:

        try {
            TimeUnit.SECONDS.wait(1); //todo remove after testing 
            InputStream input = socket.getInputStream();
            reader = new BufferedReader(new InputStreamReader(input));
        }
        catch (IOException | InterruptedException e) {
            client.clientWrite("Error getting input stream: " + e.getMessage());
        }  
    

    运行Client并查看问题是否变得明显。 要修复它,您需要从EDT上删除任何长进程。
    一种简单的方法是在不同的线程上运行长进程

    下面是submitBtnClicked修改后的内容:

      private void submitBtnClicked() {
            String hostName = ipJtf.getText();
            int port = Integer.parseInt(portJtf.getText());
            String name = nameJtf.getText();
    
            if (!name.trim().equals("")) {
    
                jta.setText("");
                jta.append(javax.swing.SwingUtilities.isEventDispatchThread() + "\n");
                jta.append("Connecting...\n");
                new Thread(()->{//take long process off the EDT 
                      try {
    
                          socket = new Socket(hostName, port);
                          //Modifying a Swing component must be done by the EDT 
                          SwingUtilities.invokeLater(()-> jta.append("Connected to server on: " + hostName + " : " + port + "\n"));
    
                          writer = new PrintWriter(socket.getOutputStream(), true);
                          writer.println(name);
    
                          new ReadThread(socket, this).start();
                          new WriteThread(socket, this).start();
    
                      }
                      catch (UnknownHostException ex) {
                           SwingUtilities.invokeLater(()-> jta.append("Server not found: " + ex.getMessage() + "\n"));
                      }
                      catch (IOException e) {
                          SwingUtilities.invokeLater(()-> jta.append("I/O Error: " + e.getMessage() + "\n"));
                      }
                }).start();
            }
            else {
                jta.setText("");
                jta.append("Please enter a user name before connecting.\n");
            }
        }
    

    (在线运行here