答えがどこにも見つからないようです。Javaでソケットを取得し、そのファイル記述子番号を渡して、Cバイナリで使用できるようにしています(fdは引数になります)。
リフレクションを使用してFileDescriptorを取得しましたが、実際の番号にはどこからもアクセスできません。
他の人がJNIを提案していることは知っていますが、可能であればJava内に保持したいと思います(そして、その方法を完全に理解できませんでした)。
答えがどこにも見つからないようです。Javaでソケットを取得し、そのファイル記述子番号を渡して、Cバイナリで使用できるようにしています(fdは引数になります)。
リフレクションを使用してFileDescriptorを取得しましたが、実際の番号にはどこからもアクセスできません。
他の人がJNIを提案していることは知っていますが、可能であればJava内に保持したいと思います(そして、その方法を完全に理解できませんでした)。
Java 7では、をにキャストしSocketInputStream
、FileInputStream
を呼び出してオブジェクトgetFD()
を取得できFileDescriptor
ます。
次に、リフレクションを使用してFileDescriptorオブジェクトのprivate int fd
フィールドにアクセスできます。(このClass.getDeclaredField(...)
メソッドを使用してフィールドを取得し、を呼び出してField.setAccessible(true)
から、を使用してフィールドの値を取得しますField.getInt(...)
。)
これを行うことで、コードプラットフォームを依存させる可能性があることに注意してください。特定のプライベートフィールドが古いバージョンまたは今後のバージョンのJava、または他のベンダー/サプライヤーによって行われるJavaの実装に存在するという保証はありません。
Stephen Cの答えは、を取得する方法を扱ってFileDescriptor
いますが、これがそのオブジェクトからのファイル記述子番号へのメソッドです。Windowsでは、内部ではなくをFileDescriptor
使用するため、このメソッドは最初に使用されているかどうかを確認し、使用されている場合はそれを返します。使用されていない場合は、にフォールバックします。OPが使用しているため、これをソケットでテストしていませんが、JVMはまだを使用していると思います。long handle
int fd
handle
fd
Windows
handle
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;
}