使用 JNI 通过 UNIX 域套接字发送 Java FD



我正在为Android编写一个应用程序,它传递了一个从ParcelFileDescriptor.getFd()获取的JAVA fd,根据[1],它指出我得到的int是一个原生fd。

现在,有了这个 fd,我正在尝试通过 unix 域套接字将其写入正在侦听的现有进程。为此,我使用 JNI,并将上面收到的 int 作为名为 fdToSend 的参数传递给 JNI 函数。

当我的 JNI 代码尝试调用 sendmsg() 时,会出现一个错误,指出"文件编号错误"。

在谷歌的帮助下,当我调用 sendmsg() 时,套接字连接似乎可能会关闭,但我看不出情况如何。

sendfd() 方法与 [2] 中的一模一样。

下面是我的桥接 JNI 函数:

JNIEXPORT jint JNICALL Java_com_example_myapp_AppManager_bridgeSendFd(JNIEnv *env, jint fdToSend) {
    int fd;
    struct sockaddr_un addr;
    if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        __android_log_print(ANDROID_LOG_ERROR, APPNAME, "socket() failed: %s (socket fd = %d)n", strerror(errno), fd);
        return (jint)-1;
    }
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, "/data/data/com.example.myapp/sock_path", sizeof(addr.sun_path)-1);
    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        __android_log_print(ANDROID_LOG_ERROR, APPNAME, "connect() failed: %s (fd = %d)n", strerror(errno), fd);
        return (jint)-1;
    }
    return (jint)sendfd(fd, (int)fdToSend);
}

[1] http://developer.android.com/reference/android/os/ParcelFileDescriptor.html#getFd()

[2] https://stackoverflow.com/a/4491203/2796346

事实证明,问题是 JNI 函数声明。

第一个参数是JNIEnv,第二个是jclass THEN,然后它是从Java传入的值(即对我来说,fdToSend)。

所以,我的猜测是,由于我使用的是第二个 arg(应该是 jclass),那么我可能会得到一个内存引用或类似的东西。

如图所示: https://stackoverflow.com/a/10743451/2796346

最新更新