Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/207.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用socketpair在两个进程之间通信时recvmsg返回错误(EBADF)?_Android_Linux_Sockets_Ipc - Fatal编程技术网

Android 使用socketpair在两个进程之间通信时recvmsg返回错误(EBADF)?

Android 使用socketpair在两个进程之间通信时recvmsg返回错误(EBADF)?,android,linux,sockets,ipc,Android,Linux,Sockets,Ipc,我正在开发一个在两个进程之间执行IPC调用的程序。我使用socketpair创建两个套接字fd: int fds[2] = {-1,-1}; if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) { return NULL; } 在进程A(具有系统权限)中,我通过发送(使用fd[0])函数发送一个整数(句柄): int sock_send_all(int sock_fd, const uint8_t* buf, int len) {

我正在开发一个在两个进程之间执行IPC调用的程序。我使用socketpair创建两个套接字fd:

int fds[2] = {-1,-1};
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
    return NULL;
}
在进程A(具有系统权限)中,我通过发送(使用fd[0])函数发送一个整数(句柄):

int sock_send_all(int sock_fd, const uint8_t* buf, int len) {  
    int s = len;
    int ret = send(sock_fd, buf, s, 0);
    ...
}  
在进程B(具有用户权限)中,它等待通过recvmsg接收句柄(使用fd[1]):

这里出现问题:recvmsg立即返回-1,其中errorno等于9(EBADF)

我上网很久了,试图找到答案,但没有任何有用的信息。你有什么提示或建议吗?谢谢


这是关于进程特权级别的问题吗?或者我应该使用setsockopt来设置一些内容?

除非我不知道IBinder的某些内容,否则一个进程中的句柄在另一个进程中无效。为什么你不能继续使用原来的插座?

我已经解决了我的问题。
关键是将原始文件描述符封装到ParcelFileDescriptor对象中,并将该对象传输到另一个进程,而不是在两个进程之间直接传输文件描述符。
我认为在android中实现的ParcelFileDescriptor对原始文件描述符进行了一些配置。也许我应该阅读实现代码来找到真正的原因。
谢谢大家

进程B是如何获得fd[1]的?@EJP:我实际上是在Android平台上开发我的程序的。进程B是IBinder(Android IPC机制)的客户端进程。简单地说,fd[1]是通过另一个unix套接字接收的(我认为Android使用unix套接字在内核中实现IBinder驱动程序)。我确认在调用send和recvmsg之前,fd[0]和fd[1]的值与从socketpair返回的值相同。请显示用于发送和接收文件描述符的代码。此外,出于特权考虑,您可以在非特权情况下测试代码。你确定你所谓的“系统权限”应用程序真的有吗?仅仅在清单中声明它是不可能的。我正在Android中移植一些现有的代码,重写是一项漫长而乏味的工作:)这种交换没有多大意义。首先,像unix域sockets一样,Binder可以通过“魔法”传递可用的文件描述符,但在问题代码中没有证据表明这样做。回应中的评论毫无意义,因为它反对重新编写,而Binder只有在非Android代码被重写以使用Binder而不是unix套接字时才会成为一个因素…@ChrisStratton表示同意。整个事情对我来说没有意义。我有同样的问题,这也是我的解决方案。ParcelFileDescriptor必须作为其包在进程间传输,然后在到达另一个进程后重新序列化为ParcelFileDescriptor。传递原始int ParcelFileDescriptor.fd值是不够的。Unix/Android可能会为每个进程分配不同的int-fd值,这些值指向相同的底层管道。
ret = recvmsg(fd, &msg, MSG_NOSIGNAL);