java - 如何通过套接字传递 FTP 服务器的目录结构并使用 JTree 将其显示在客户端的 GUI 中

标签 java swing sockets network-programming jtree

我正在用 JAVA 创建一个 FTP 应用程序,用于在服务器和客户端之间传输文件。我已经为客户端创建了一个 GUI,它应该在左侧显示客户端目录结构,在右侧显示服务器目录结构,但我无法弄清楚如何传递服务器的目录结构并将其显示在客户端的 GUI 上。我尝试将它作为对象从服务器传递并在客户端读取它,但不知道如何将它传递到服务器的 JTree。不过,我可以在 GUI 上显示客户端目录结构。我尝试四处寻找解决方案,但找不到任何对我的情况有帮助的解决方案。任何帮助将不胜感激。

下面是我正在使用的类。我现在只使用一个简单的客户端和服务器类,它们在建立连接时互相发送消息:

这是我的服务器类:

public class SimpleServer {

    public FileSystemModel systemModel;

    public static void main(String[] args) throws IOException {
        SimpleServer s = new SimpleServer();
        s.run();
    }

    public void run() throws IOException{
        ServerSocket serverSoc = new ServerSocket(150);
        System.out.println("Server up and running on port 150");
        Socket soc = serverSoc.accept();

        PrintStream ps = new PrintStream(soc.getOutputStream());
        ps.println("Welcome");

        InputStreamReader is = new InputStreamReader(soc.getInputStream());
        BufferedReader br = new BufferedReader(is);

        String message = br.readLine();
        System.out.println(message);

        //Not sure if this works
        ObjectOutputStream oOut = new ObjectOutputStream(soc.getOutputStream());
        String dir = "C:/Users/David/Desktop/Server/";
        systemModel = new FileSystemModel(new File(dir));
        oOut.writeObject(systemModel);

        /*if (message != null){
            PrintStream ps = new PrintStream(soc.getOutputStream());
            ps.println("Message Received");
        }*/
    }
}

这是我的客户类:

public class SimpleClient {

    Socket soc;

    public void run() throws UnknownHostException, IOException {

        soc = new Socket("localhost", 150);

        InputStreamReader is = new InputStreamReader(soc.getInputStream());
        BufferedReader br = new BufferedReader(is);

        String message = br.readLine();
        System.out.println(message);

        if (message != null) {
            PrintStream ps = new PrintStream(soc.getOutputStream());
            ps.println("Message Received");
        }
    }

    //Not sure if this method is working
    public Object getObject() throws Exception {
        ObjectInputStream oIn = new ObjectInputStream(soc.getInputStream());
        Object model = oIn.readObject();
        return model;
    }
}

这个类在我的 GUI 中用于显示 JTree 中的目录结构。目前只能显示客户端的目录结构。

class FileSystemModel implements TreeModel, Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private File root;

    private Vector<TreeModelListener> listeners = new Vector<TreeModelListener>();

    public FileSystemModel(File rootDirectory) {
        root = rootDirectory;
    }

     //All the other implemented methods from TreeModel goes here


    private void fireTreeNodesChanged(TreePath parentPath, int[] indices,
            Object[] children) {
        TreeModelEvent event = new TreeModelEvent(this, parentPath, indices,
                children);
        Iterator<TreeModelListener> iterator = listeners.iterator();
        TreeModelListener listener = null;
        while (iterator.hasNext()) {
            listener = iterator.next();
            listener.treeNodesChanged(event);
        }
    }

    private class TreeFile extends File {
        /**
     * 
     */
        private static final long serialVersionUID = -5775093232151119831L;

        public TreeFile(File parent, String child) {
            super(parent, child);
        }

        @Override
        public String toString() {
            return getName();
        }
    }
}

最后这是我的 GUI 类,它显示两个 JTree。客户端的目录结构在左侧,服务器的目录结构在右侧,我在显示时遇到问题:

public class GUI extends JFrame {

    private JPanel contentPane;
    private FileSystemModel systemModel;
    private SimpleClient c;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    GUI frame = new GUI();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     * @throws Exception 
     */
    public GUI() throws Exception {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);

        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);

        JMenu mnFile = new JMenu("File");
        menuBar.add(mnFile);

        //Connect Button
        JMenuItem mntmConnect = new JMenuItem("Connect");
        mntmConnect.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                c = new SimpleClient();
                try {
                    c.run();
                } catch (UnknownHostException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }   
            }
        });

        mnFile.add(mntmConnect);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JSplitPane splitPane = new JSplitPane();
        contentPane.add(splitPane, BorderLayout.CENTER);

        String dir = "C:/Users/David/Desktop/Client/";

        systemModel = new FileSystemModel(new File(dir));

        final JTree treeClient = new JTree(systemModel);
        treeClient.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent arg0) {
                File file = (File) treeClient.getLastSelectedPathComponent();
                //fileDetailsTextArea.setText(getFileDetails(file));
                System.out.println(getFileDetails(file));
            }
        });
        splitPane.setLeftComponent(treeClient);

        //This is where I want to pass the server's directory structure
        JTree treeServer = new JTree();
        splitPane.setRightComponent(treeServer);    
    }

    private String getFileDetails(File file) {
        // returns details of the file clicked
    }

}

最佳答案

您可以通过序列化将对象从一个套接字发送到另一个套接字。只需将您的树模型发送过来即可。请注意,DefaultMutableTreeNode 实现了可序列化。

我不会发送文件对象(尽管它也是可序列化的),只会发送字符串。也不需要发送 TreeModel 实例,发送 DefaultMutableTreeNode 就足够了,您可以在接收端构建您的 TreeModel。只需确保您的对象图仅包含可序列化的对象。

关于java - 如何通过套接字传递 FTP 服务器的目录结构并使用 JTree 将其显示在客户端的 GUI 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15028844/

相关文章:

java - 未安装名为 "org.mariadb.jdbc.Driver"的 JBOSS 驱动程序

java - 如何在 Android 上执行 HttpRequest 时显示 ProgressDialog?

java - 如何重新加载 JPanel?

c - 发送数据包时如何设置iptables标记?

c++ - 有没有办法阻止套接字 send() 直到我们得到该数据包的确认?

linux - ZeroMQ 与 Qt 5.12 QSocketNotifier 仅触发一次

java - Elasticsearch,文档中数组大小的总和

java - "No such column name"错误

Java 在 Windows 资源管理器中选择文件?

java - Java Swing 中具有设置像素高度的项目的可滚动列表