zoukankan      html  css  js  c++  java
  • 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 ativelibsinputInputTransport.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] = ''

        printf("%s ",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] = ''

        printf("%s ",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

  • 相关阅读:
    为什么杜蕾斯的文案工资月薪5万?
    在独立音乐上,网易云音乐是如何甩了其他音乐平台几条街?
    两次大战,为什么德国成不了世界霸主呢?
    在大城市打拼的你,是想留下还是想攒够了钱回家?
    生存在互联网公司是种怎样的体验?
    5G为何采纳华为力挺的Polar码?一个通信工程师的大实话
    放下恩怨,曝小米中兴投关键性一票让华为顺利取得5G短码控制权
    中国唯一的科技城
    互联网圈的6大奇葩大产品经理:张小龙不在乎手机碎屏,马化腾让用户一秒变白痴
    为什么说中国快递分两种:一种叫顺丰,一种叫快递?
  • 原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/9160921.html
Copyright © 2011-2022 走看看