在Android中重定向C程序的STDIN和STDOUT

Emm*_*ohn 3 c java java-native-interface android android-ndk

我正在尝试使用JNI将C程序移植到android.我已经能够设置程序并使java和c一起正常工作.问题是我需要能够使用STDIN,因为C程序从STDIN读取输入并通过STDOUT返回响应(C程序是服务器 - 客户端应用程序).我不知道是否值得一提,但C程序使用STDIN_FILENO文件描述符来读取STDIN的输入. 如何使用Java从STDOUT和WRITE读取到STDIN?

我做了一些研究,并在以下链接中找到了一些模糊的解释:https://groups.google.com/forum/#!topic / installer -ndk/Brm6jPr4C0Y,我不明白.

这是C代码https://github.com/unekwu/kemi/blob/master/jni/dnscat/dnscat.c#L1270

更多细节

C程序通常从命令行运行, dnscat --dns <ip> <port> 之后它开始侦听来自用户的消息.通常从stdin输入.

现在在我的Android应用程序中,我可以通过调用main和不同的名称并将ann数组字符串传递给它来运行它与JNI.我验证程序是否开始纠正.问题是我将如何将消息发送到程序,因为android上没有stdin.

Man*_*ani 7

我在github上创建了一个项目,你可以从这里下载.

它创建了2个命名管道(FIFO),一个用于输入,另一个用于输出.

它在本机代码中以只写模式打开管道的一端,在Java代码中以只读模式打开管道的另一端.本机代码中的文件描述符映射到STDOUT,即1,此后对本机代码中的STDOUT的任何写入将被重定向到可以用Java代码读取的管道的另一端.

它在本机代码中以只读模式打开管道的一端,在Java代码中以只写模式打开管道的另一端.本机代码中的文件描述符映射到STDIN,即0,此后对Java代码中管道的另一端的任何写入将由本机代码使用STDIN读取.

要实现STDOUT重定向:

本地代码:

    /*
     * Step 1: Make a named pipe
     * Step 2: Open the pipe in Write only mode. Java code will open it in Read only mode.
     * Step 3: Make STDOUT i.e. 1, a duplicate of opened pipe file descriptor.
     * Step 4: Any writes from now on to STDOUT will be redirected to the the pipe and can be read by Java code.
     */
    int out = mkfifo(outfile, 0664);
    int fdo = open(outfile, O_WRONLY);
    dup2(fdo, 1);
    setbuf(stdout, NULL);
    fprintf(stdout, "This string will be written to %s", outfile);
    fprintf(stdout, "\n");
    fflush(stdout);
    close(fdo);
Run Code Online (Sandbox Code Playgroud)

Java代码:

/*
 * This thread is used for reading content which will be written by native code using STDOUT.
 */

new Thread(new Runnable() {

    @Override
    public void run() {
        BufferedReader in = null;
        try {
            in = new BufferedReader(new FileReader(mOutfile));
            while(in.ready()) {
                final String str = in.readLine();
                mHandler.post(new Runnable() {

                    @Override
                    public void run() {

                        Toast.makeText(RedirectionJni.this, str, Toast.LENGTH_LONG).show();
                    }

                });
            }
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();
Run Code Online (Sandbox Code Playgroud)

要实现STDIN重定向:

本地代码:

    /*
     * Step 1: Make a named pipe
     * Step 2: Open the pipe in Read only mode. Java code will open it in Write only mode.
     * Step 3: Make STDIN i.e. 0, a duplicate of opened pipe file descriptor.
     * Step 4: Any reads from STDIN, will be actually read from the pipe and JAVA code will perform write operations.
     */
    int in = mkfifo(infile, 0664);
    int fdi = open(infile, O_RDONLY);
    dup2(fdi, 0);
    char buf[256] = "";
    fscanf(stdin, "%*s %99[^\n]", buf); // Use this format to read white spaces.
    close(fdi);
Run Code Online (Sandbox Code Playgroud)

Java代码:

/*
 * This thread is used for writing content which will be read by native code using STDIN.
 */
new Thread(new Runnable() {

    @Override
    public void run() {
        BufferedWriter out = null;
        try {
                out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(mInfile)));
            String content = "This content is written to " + mInfile;
            out.write(content.toCharArray(), 0, content.toCharArray().length);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();
Run Code Online (Sandbox Code Playgroud)

如果您需要任何帮助,请告诉我.