带GUI的Java套接字客户端

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带GUI的Java套接字客户端相关的知识,希望对你有一定的参考价值。

我正在尝试为我的学校项目构建一个客户端套接字应用程序,它允许您将文件发送到服务器。我构建它,我打开服务器,服务器在等待连接时正常工作。在我打开客户端并选择一个带有JFileChooser的文件并单击发送后,它会起作用,因为服务器会收到该文件。但是,如果我尝试选择一个文件并再次点击发送它就不起作用。有人可以帮忙吗?

服务器代码:

public class NewServer {

public static void main(String[] args) throws Exception {

    ServerSocket serverSocket = new ServerSocket(8090);
    while (true) {
        System.out.println("Waiting for client...");
        Socket sock = serverSocket.accept();
        System.out.println("Client connected!");

        DataInputStream in = new DataInputStream(sock.getInputStream());
        DataOutputStream out = new DataOutputStream(sock.getOutputStream());
        FileOutputStream fout = null;

        String ip = in.readUTF();
        String fileName = in.readUTF();
        System.out.println("User with IP " + ip + " is sending a file with name " + fileName);
        fout = new FileOutputStream(fileName);

        System.out.println("Receiving file...");
        int count;
        byte[] buffer = new byte[1024];
        while ((count = in.read(buffer)) > 0) {
            fout.write(buffer, 0, count);
        }
        System.out.println("File received!");
        out.close();
        in.close();
        fout.close();

    }
}

}

图形界面:

public class Frame extends JFrame {

Frame() throws Exception {
    JFrame frame = new JFrame("Client");
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(300, 400);
    Socket sock = new Socket("localhost", 8090);

    JPanel panel = new JPanel();
    JButton send = new JButton("Send File");
    JButton select = new JButton("Select File");
    JLabel label = new JLabel();

    panel.setLayout(new GridLayout(3, 4, 5, 10));
    panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    frame.add(panel);
    panel.add(select);
    panel.add(send);
    panel.add(label);
    send.setEnabled(false);


    select.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            JFileChooser chooser = new JFileChooser();
            // optionally set chooser options ...
            if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
                File file = chooser.getSelectedFile();
                label.setText(file.getName());
                send.setEnabled(true);
            } else {
                send.setEnabled(false);
            }
        }
    }
    );
    send.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            FileInputStream fin = null;
            DataInputStream in = null;
            DataOutputStream out = null;
            try {
                fin = new FileInputStream(label.getText());
                in = new DataInputStream(sock.getInputStream());
                out = new DataOutputStream(sock.getOutputStream());

                out.writeUTF(sock.getLocalAddress().toString());
                out.writeUTF(label.getText());
                out.flush();

                int count;
                byte buffer[] = new byte[1024];
                while ((count = fin.read(buffer)) > 0) {
                    out.write(buffer);
                }
            } catch (Exception ex) {
                ex.getMessage();
            } finally {
                try {
                    sock.close();
                    send.setEnabled(false);
                } catch (IOException ex) {
                    ex.getMessage();
                }

            }

        }

    });

}

}

在主要我只是创建一个GUI的实例:

public class NewClient {

public static void main(String[] args) throws Exception {

    Frame frame = new Frame();

}

}

如果有人可以提供帮助那就太棒了!非常感谢你

答案

sock.close();

第一次使用后关闭套接字。

你需要把

Socket sock = new Socket("localhost", 8090);

actionPerformed(ActionEvent e)send方法中。

send.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        Socket sock = new Socket("localhost", 8090);
        FileInputStream fin = null;
        ...

基于下面的Gregoris反馈,我建议正确的线程不会调用actionPerformed监听器来创建套接字,如果它正在关闭它,这是令人惊讶的。

底线是一个封闭的插座,不能重复使用,这绝对是功课。

以上是关于带GUI的Java套接字客户端的主要内容,如果未能解决你的问题,请参考以下文章

带 GUI 的多线程客户端/服务器聊天室

在摆动小程序中使用的套接字

java socket网络编程

Docker运行GUI软件的方法

在使用之间保存 Java GUI 布局配置(带桌面窗格)

套接字编程中的Java拖放问题