【问题标题】:How to communicate with a Virtual Machine in Java?Java如何与虚拟机通信?
【发布时间】:2014-05-03 16:20:03
【问题描述】:

我制作了一个 Java 小程序,要求人们输入密码。输入 pin 码后,它会立即读入一个“bdd.txt”文件,其中存储了所有 pin,然后显示 :) 是否正确和 :( 如果错误。到目前为止是简单的应用程序。

我想做的是将那个“数据库”文件移动到我计算机上的虚拟机中(例如 Ubuntu),然后做同样的事情。这样,它就不再是本地的了,因为该文件将不再位于我的项目的根目录中。

这是我的应用程序的样子:

如您所见,应用启动后,要求用户输入 PIN 码。如果这是一个好的,应用程序就完成了,如果不是,他还有 2 次尝试,直到应用程序停止。

输入 pin 后,我的程序会检查“bdd.txt”是否存在 pin。它扮演数据库角色:

要了解我需要什么,有必要将此程序同化为需要安全的东西。我们不希望引脚数据库与程序(或现实生活中的设备)位于同一位置。所以我们把它放在一个虚拟机上,我们必须在 Eclipse 中的 Windows7 Java 程序和 VMWare Player 的 Ubuntu 上的 bdd.txt 文件之间进行通信。

我的问题是这怎么可能?我如何需要更改我的代码以让我的程序到达我的 VM 上的某些内容?有没有我应该使用的规范技术?我需要先做一些配置吗?

这是我的代码:

import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.PlainDocument;
import java.awt.*;
import java.awt.event.*;

public class Main extends JFrame {

    private static final long serialVersionUID = 1L;

    private JPanel container = new JPanel();
    private JPasswordField p1 = new JPasswordField(4);
    private JLabel label = new JLabel("Enter Pin: ");
    private JButton b = new JButton("OK");


    public Main() {
        this.setTitle("NEEDS");
        this.setSize(300, 500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);

        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());
        container.add(p1);
        JPanel top = new JPanel();

        PlainDocument document =(PlainDocument)p1.getDocument();

        b.addActionListener(new BoutonListener());

        top.add(label);
        top.add(p1);
        p1.setEchoChar('*');
        top.add(b);  

        document.setDocumentFilter(new DocumentFilter(){

            @Override
            public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
                String string =fb.getDocument().getText(0, fb.getDocument().getLength())+text;

                if(string.length() <= 4)
                super.replace(fb, offset, length, text, attrs); //To change body of generated methods, choose Tools | Templates.
            }
        });


        this.setContentPane(top);
        this.setVisible(true);
    }

    class BoutonListener implements ActionListener {
        private final AtomicInteger nbTry = new AtomicInteger(0);
        ArrayList<Integer> pins = readPinsData(new File("bdd.txt"));

        @SuppressWarnings("deprecation")
        public void actionPerformed(ActionEvent e) {
            if (nbTry.get() > 2) {
                JOptionPane.showMessageDialog(null,
                        "Pin blocked due to 3 wrong tries");
                return;
            }
            final String passEntered=p1.getText().replaceAll("\u00A0", "");
            if (passEntered.length() != 4) {
                JOptionPane.showMessageDialog(null, "Pin must be 4 digits");
                return;
            }
            //JOptionPane.showMessageDialog(null, "Checking...");
            //System.out.println("Checking...");
            SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
                @Override
                protected Void doInBackground() throws Exception {
                    boolean authenticated = false;

                    if (pins.contains(Integer.parseInt(passEntered))) {
                        JOptionPane.showMessageDialog(null, ":)");
                        authenticated = true;
                    }

                    if (!authenticated) {
                        JOptionPane.showMessageDialog(null, ":(");
                        nbTry.incrementAndGet();
                    }
                    return null;
                }
            };
            worker.execute();
        }

    }

    //Function to read/access my bdd.txt file
    static public ArrayList<Integer> readPinsData(File dataFile) {
        final ArrayList<Integer> data=new ArrayList<Integer>();
        try {
            BufferedReader reader = new BufferedReader(new FileReader(dataFile));
            String line;
            try {
                while ((line = reader.readLine()) != null) {
                    try {
                        data.add(Integer.parseInt(line));
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                        System.err.printf("error parsing line '%s'\n", line);
                    }
                }
            } finally {
                reader.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("error:"+e.getMessage());
        }

        return data;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Main();
            }
        });

    }
}

有什么想法吗?谢谢,

弗洛伦特。

【问题讨论】:

  • 您是否考虑过添加一个应用程序可以看到并且VM 可以读取的共享文件夹?我认为 VirtualBox 支持类似的东西。
  • 如果程序可以访问 pin 列表,那么用户也可以。 pin检查应该由用户无权访问的机器执行,并且您的程序通过安全通道连接到该机器。 SSL/TLS 是一种简单的方法,当然还有其他方法。
  • 基本上,在您的计算机上运行的 VM 与通过网络连接的房间内的单独计算机之间没有区别。两种情况都可以使用相同的选项,并且需要基本相同的设置。

标签: java linux eclipse web-services virtual


【解决方案1】:

共享文件夹当然可以,但拥有虚拟机似乎没什么意义,因为 PIN 文件也在您的主机上,而 java 正在直接读取它。

也许您需要客户端/服务器架构?

您使用 UI 编程将成为客户端。客户端将配置调用服务器的方法(IP 地址和端口)。客户端无权访问 bdd.txt 文件,但服务器有。

在您的 VM 上,您有另一个 java 应用程序,即服务器。您的服务器侦听来自客户端的请求。该请求将包含用户输入的 PIN。然后服务器根据文件中的 PIN 检查它,并以“是”或“否”作为响应。您的客户端收到来自服务器的是/否响应,并将结果报告给用户。

阅读 Sockets 编程here 以开始使用

【讨论】:

  • 是的,我想就是这样。客户端服务器架构,还是同时使用 Web 服务?
  • Web 服务可以解决问题,并且有一些 Java HTTP 服务器可供选择。其中,我只使用了 Tomcat,不过,这对于这个应用程序来说似乎有点过头了。
  • 好的,谢谢,这意味着我将不得不大幅修改代码对吗?
  • 并非如此 - 您的大部分代码将进入您的客户端应用程序而无需太多更改,只有方法 readPinsData 将被移动到新的服务器应用程序和您的客户端应用程序中,而不是读取文件,将与服务器通信。
  • 我试图实现一些东西,但没有什么好的结果。我怎样才能以这种方式访问​​文件? (我尝试使用套接字)
【解决方案2】:

你需要做两件事:

  1. 在主机操作系统和 VM 之间共享一个文件夹。这将允许您的虚拟机从主机操作系统访问文件。您可能希望将您的 pin 文件放在此文件夹中。
  2. 让您的应用程序从共享文件夹中读取 pin 文件。这意味着改变这一行:

    ArrayList&lt;Integer&gt; pins = readPinsData(new File("bdd.txt"));

    现在,此代码正在从用户所在的当前目录中读取文件 bdd.txt,我假设该目录是您的可执行文件所在的目录。相反,您希望它指向共享目录中的 pin 文件.为了使您的代码尽可能灵活,您可能希望在启动程序时将 pin 文件的路径作为命令行参数传递。

【讨论】:

  • 实际上我在考虑避免这种获取文件的方式。这一切都与安全有关。该文件必须远离程序。我在想:网络服务?
猜你喜欢
  • 1970-01-01
  • 2021-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 2016-10-27
相关资源
最近更新 更多