【问题标题】:Java WINAPI Anonymous Pipe Invalid/Not Found?Java WINAPI 匿名管道无效/未找到?
【发布时间】:2018-08-06 22:25:36
【问题描述】:

Java 似乎无法从 WinAPI 继承匿名管道,我正在使用自己的库,但无法弄清楚问题所在。

Library source on the current commit.

匿名测试:

package net.gudenau.lib.pipes.test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import net.gudenau.lib.pipes.AnonymousPipeHandle;
import net.gudenau.lib.pipes.PipeHandle;
import net.gudenau.lib.pipes.Pipes;

public class AnonymousPipe{
    public static void main(String[] args){
        try(PipeHandle client = Pipes.findPipe()){
            InputStream inputStream = client.getInputStream();
            OutputStream outputStream = client.getOutputStream();

            byte[] data = "This is from the anon pipe!".getBytes(StandardCharsets.UTF_16);
            outputStream.write(data.length);
            outputStream.write(data);
            data = new byte[inputStream.read()];
            inputStream.read(data);
            System.out.printf("Server says: %s\n", new String(data, StandardCharsets.UTF_16));
        }catch(IOException e){
            e.printStackTrace();
            System.exit(0);
        }
    }

    static void test(){
        File path = new File(System.getProperty("java.home") + File.separator + "bin");
        File executable;
        if(System.getProperty("os.name").toLowerCase().contains("windows")){
            executable = new File(path, "javaw.exe");
        }else{
            executable = new File(path, "java");
        }

        ProcessBuilder processBuilder = new ProcessBuilder(
            executable.getAbsolutePath(),
            "-Dfile.encoding=UTF-8",
            "-classpath",
            System.getProperty("java.class.path"),
            "net.gudenau.lib.pipes.test.AnonymousPipe"
        );
        processBuilder.inheritIO();

        try(AnonymousPipeHandle pipe = Pipes.createPipe()){
            pipe.setupHandleShare(processBuilder);
            Process process = processBuilder.start();
            pipe.clientConnected();

            InputStream inputStream = pipe.getInputStream();
            OutputStream outputStream = pipe.getOutputStream();

            byte[] data = new byte[inputStream.read()];
            inputStream.read(data);
            String message = new String(data, StandardCharsets.UTF_16);
            System.out.printf("Client says: %s\n", new String(data, StandardCharsets.UTF_16));
            data = message.toUpperCase().getBytes(StandardCharsets.UTF_16);
            outputStream.write(data.length);
            outputStream.write(data);

            try{
                process.waitFor();
            }catch(InterruptedException ignored){}
        }catch(IOException e){
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

据我所知,我所做的一切都是正确的。

我正在使用SECURITY_ATTRIBUTESbInheritHandle 设置为true 来创建带有CreatePipe 的匿名管道。

然后在创建客户端后,我关闭“客户端”端句柄。

我错过了什么?

编辑:我间隔并错过了错误。 test 方法抛出 The specified procedure could not be found.,至少根据 Windows,这对我来说毫无意义。

另一个进程抛出The handle is invalid.,同样根据Windows。

输出:

Client says: the quick brown fox jumps over the lazy dog
Server says: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
java.io.IOException: The specified procedure could not be found.

    at net.gudenau.lib.pipes.impl.windows.WindowsPipeInputStream.read(WindowsPipeInputStream.java:34)
    at java.base/java.io.InputStream.read(InputStream.java:106)
    at net.gudenau.lib.pipes.impl.windows.WindowsPipeInputStream.read(WindowsPipeInputStream.java:16)
    at net.gudenau.lib.pipes.test.AnonymousPipe.test(AnonymousPipe.java:57)
    at net.gudenau.lib.pipes.test.PipeTest.main(PipeTest.java:6)
java.io.IOException: The handle is invalid.

    at net.gudenau.lib.pipes.impl.windows.WindowsPipeOutputStream.write(WindowsPipeOutputStream.java:35)
    at java.base/java.io.OutputStream.write(OutputStream.java:77)
    at net.gudenau.lib.pipes.impl.windows.WindowsPipeOutputStream.write(WindowsPipeOutputStream.java:15)
    at net.gudenau.lib.pipes.test.AnonymousPipe.main(AnonymousPipe.java:19)

Process finished with exit code -1

【问题讨论】:

    标签: java windows winapi pipe anonymous-pipes


    【解决方案1】:

    我记得读过here,一个进程的句柄在另一个进程中无效,Java windows 匿名管道只在线程之间工作。这可以解释无效的句柄。

    【讨论】:

    • Pipe Handle Inheritance 不同意最初的说法。
    • 当然处理每个流程值,并且仅在流程上下文中有意义。但是继承 - 这是当句柄从具有相同值的父进程复制到子进程时。你的意思是只在线程之间工作我完全不明白。
    • 我的观点是,如果子进程有不同的 pid(它应该),那么匿名管道的句柄是无效的,除非你用重复句柄(forums.codeguru.com/…)修复它
    • 现在我可能会使用它,我会研究一下。
    • DuplicateHandle 表示句柄无效。多么奇怪。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多