10.2、android输入系统_必备Linux编程知识_双向通信(scoketpair)

2. 双向通信(socketpair)

输入系统肯定涉及进程通讯:进程A读取/分发输入事件,APP处理输入事件,进程A给APP发送输入事件,APP处理完事件回复信息给进程A,APP关闭的时候也要发信息给进程A

binder用在进程间双向通信的时候的确定:每次请求只能由client单方发起

因此如果使用binder来实现双向通信,client也要提供server功能,server也要提供client功能

这里引入socketpair,其实现原理如下:

APP调用socketpair对得到两个文件句柄fd1和fd2:

fd1和fd2在内核空间中有两个buf,send_buf1、send_buf2和rcv_buf1、rcv_buf2,应用程序通过fd1把数据写到send_buf1,内核里的socketpair会把send_buf1的数据写入rcv_buf2,同理数据也可以主动从send_buf2到rcv_buf1

socketpair的缺点是其只适应于线程间通信或者有亲缘关系的进程,比如父子进程间通信,因为fd1和fd2又调用socketpair的进程创建,不能被其他进程得到;因此这个时候如果还有一个APP2如果想和APP1双向通信,怎么办?

利用binder得到fd2,在APP2中这个文件句柄是fd3,就可以和fd1通信了

参考代码:
frameworks\native\libs\input\InputTransport.cpp (socketpair)
调用过程
WindowManagerService.java
  InputChannel.openInputChannelPair(name)
    nativeOpenInputChannelPair(name);
      android_view_InputChannel_nativeOpenInputChannelPair
        InputChannel::openInputChannelPair (InputTransport.cpp)

 

socketpair.c

#include <pthread.h>

#include <unistd.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#define SOCKET_BUFFER_SIZE (32768U)

void *function_thread1(void *arg)

{

  int fd = (int)arg

  while(1){

    /*向main线程发出,hello,main thread*/

    len = sprintf(buf,"hello,main thread,cnt = %d",cnt++);

    write(fd,buf.len);

    /*读取数据(main线程发回的数据)*/

    len = read(fd,buf,500);

    buf[len] = '\0'

    printf("%s\n",buf);

    sleep(5);

  }

  return NULL;

}

int main(int argc,char **argv)

{

  int sockets[2];

  socketpair(AF_UNIX,SOCK_SEQPACKET,0,sockets);

  //给fd1和fd2创建sendbuf和rcvbuf

  int bufferSize = SOCKET_BUFFER_SIZE;

  setsockopt(sockets[0],SOL_SOCKET,SO_SNDBUF,*bufferSize,sizeof(bufferSIze));

  setsockopt(sockets[0],SOL_SOCKET,SO_RCVBUF,*bufferSize,sizeof(bufferSIze));

  setsockopt(sockets[1],SOL_SOCKET,SO_SNDBUF,*bufferSize,sizeof(bufferSIze));

  setsockopt(sockets[1],SOL_SOCKET,SO_RCVBUF,*bufferSize,sizeof(bufferSIze));

  /*创建线程1*/

  pthread_t threadID;

  pthread_create(&threadID,NULL,function_thread1,(void *)sockets[1]);

  char buf[500];

  int len;

  int cnt = 0;

  int fd = sockets[0];

  while(1){

    /*读数据:线程1发出的数据*/

    len = read(fd,buf,500);

    buf[len] = '\0'

    printf("%s\n",buf);

    /*main thread向thread1发出:Hello,thread1*/

    len = sprintf(buf,"hello,thread1,cnt = %d",cnt++);

    write(fd,buf.len);

  }

}

测试:
gcc -o socketpair socketpair.c -lpthread
./socketpair

posted on 2018-06-09 21:32  拉风摊主  阅读(234)  评论(0编辑  收藏  举报

导航