Java 在Ubuntu中连接到VPN

Java 在Ubuntu中连接到VPN,java,ubuntu,Java,Ubuntu,我使用了一个VPN服务,并使用java代码连接到它并在Ubuntu上运行它。每当sudo openvpn命令完全运行时,控制台就会卡住,不会转到while循环后的代码。但是如果我在while循环中包含sudo命令后的代码,那么它会在该命令后运行代码,而不是sudo命令。我尝试添加“&”,以便命令在后台运行,但没有任何用处。请建议一种方法来执行此操作,因为我尝试了各种解决方案,但都没有成功。下面是我编写的代码 public class curl { void sudo() throws IOE

我使用了一个VPN服务,并使用java代码连接到它并在Ubuntu上运行它。每当sudo openvpn命令完全运行时,控制台就会卡住,不会转到while循环后的代码。但是如果我在while循环中包含sudo命令后的代码,那么它会在该命令后运行代码,而不是sudo命令。我尝试添加“&”,以便命令在后台运行,但没有任何用处。请建议一种方法来执行此操作,因为我尝试了各种解决方案,但都没有成功。下面是我编写的代码

public class curl {


void sudo() throws IOException {

    String command1 = "sudo openvpn --config /etc/openvpn/configFile ";

     System.out.println(command1);



     Process curlProc1;

    curlProc1 = Runtime.getRuntime().exec(command1);



    DataInputStream curlIn1 = new DataInputStream(

            curlProc1.getInputStream());

      String outputString1;

     while ((outputString1 = curlIn1.readLine()) != null) {

        System.out.println(outputString1);

}


     String urly = "MyURL";
             URL obj = new URL(urly);
             HttpURLConnection con1 = (HttpURLConnection) obj.openConnection();

             con1.setRequestMethod("GET");

           con1.setDoOutput(true);

             int responseCode = con1.getResponseCode();
             System.out.println("Response Code : " + responseCode);

             BufferedReader iny = new BufferedReader(
             new InputStreamReader(con1.getInputStream()));
               String output;
               StringBuffer response = new StringBuffer();

               while ((output = iny.readLine()) != null) {
                response.append(output);

               }

               iny.close();
               System.out.println(response.toString());
               }

public static void main(String args[]) throws IOException, ClassNotFoundException, SQLException, JSONException{

     curl brc= new curl();
     brc.sudo();

}



}

您的问题是由sudo输出到错误流这一事实引起的。这种情况正在发生:

  • 你的程序启动sudo
  • 由于默认情况下sudo在终端上工作,因此它将“sudo:no tty present and no askpass program specified”或“Password:”输出到
    stderr
  • 您的程序等待
    stdout上的输入
  • 由于您从未读过stderr,sudo将永远不会终止,因此sudo将永远不会关闭stdout,因此您的程序将保持停滞状态
  • 解决这个问题的一个快速方法是使用,它有一个有用的选项,可以将
    stderr
    stdout
    组合在一个流中,这意味着您只需要一个线程就可以读取流,并保持代码的简单性

    ProcessBuilder pb =
        new ProcessBuilder("sudo", "openvpn", "--config", "/etc/openvpn/configFile");
    pb.redirectErrorStream(true);
    Process curlProc1 = pb.start();
    ....
    
    由于sudo可能会要求输入密码(),因此您可以在收到密码提示后,通过写入进程的输入流来提供密码:

    p.getOutputStream().write("correct battery horse staple\n".getBytes(STandardCharsets.UTF_8));
    

    在这里,Inheritaio可能是一个更好的解决方案:您能提供一个与我的代码相关的示例吗(我也尝试过这个解决方案,但问题仍然存在,它围绕着while循环。如果我关闭循环,之后的代码根本不会执行,但是sudo命令工作得很好。while循环后的代码只有在我将其添加到while循环中,但sudo命令不运行时才会执行。我们可以使用其他方法代替r吗eadLine()?可能当我在循环中添加代码时,它无法执行整个sudo命令,之后的代码会立即运行。
    ProcessBuilder pb =
        new ProcessBuilder("sudo", "openvpn", "--config", "/etc/openvpn/configFile");
    pb.redirectErrorStream(true);
    Process curlProc1 = pb.start();
    ....
    
    p.getOutputStream().write("correct battery horse staple\n".getBytes(STandardCharsets.UTF_8));