1

答えがどこにも見つからないようです。Javaでソケットを取得し、そのファイル記述子番号を渡して、Cバイナリで使用できるようにしています(fdは引数になります)。

リフレクションを使用してFileDescriptorを取得しましたが、実際の番号にはどこからもアクセスできません。

他の人がJNIを提案していることは知っていますが、可能であればJava内に保持したいと思います(そして、その方法を完全に理解できませんでした)。

4

2 に答える 2

3

Java 7では、をにキャストしSocketInputStreamFileInputStreamを呼び出してオブジェクトgetFD()を取得できFileDescriptorます。

次に、リフレクションを使用してFileDescriptorオブジェクトのprivate int fdフィールドにアクセスできます。(このClass.getDeclaredField(...)メソッドを使用してフィールドを取得し、を呼び出してField.setAccessible(true)から、を使用してフィールドの値を取得しますField.getInt(...)。)


これを行うことで、コードプラットフォームを依存させる可能性があることに注意してください。特定のプライベートフィールドが古いバージョンまたは今後のバージョンのJava、または他のベンダー/サプライヤーによって行われるJavaの実装に存在するという保証はありません。

于 2012-07-12T16:07:54.017 に答える
0

Stephen Cの答えは、を取得する方法を扱ってFileDescriptorいますが、これがそのオブジェクトからのファイル記述子番号へのメソッドです。Windowsでは、内部ではなくをFileDescriptor使用するため、このメソッドは最初に使用されているかどうかを確認し、使用されている場合はそれを返します。使用されていない場合は、にフォールバックします。OPが使用しているため、これをソケットでテストしていませんが、JVMはまだを使用していると思います。long handleint fdhandlefdWindowshandle

public static long fileno(FileDescriptor fd) throws IOException {
    try {
        if (fd.valid()) {
            // windows builds use long handle
            long fileno = getFileDescriptorField(fd, "handle", false);
            if (fileno != -1) {
                return fileno;
            }
            // unix builds use int fd
            return getFileDescriptorField(fd, "fd", true);
        }
    } catch (IllegalAccessException e) {
        throw new IOException("unable to access handle/fd fields in FileDescriptor", e);
    } catch (NoSuchFieldException e) {
        throw new IOException("FileDescriptor in this JVM lacks handle/fd fields", e);
    }
    return -1;
}

private static long getFileDescriptorField(FileDescriptor fd, String fieldName, boolean isInt) throws NoSuchFieldException, IllegalAccessException {
    Field field = FileDescriptor.class.getDeclaredField(fieldName);
    field.setAccessible(true);
    long value = isInt ? field.getInt(fd) : field.getLong(fd);
    field.setAccessible(false);
    return value;
}
于 2018-01-03T02:16:05.613 に答える