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

  • 相关阅读:
    分享25个高质量的移动设备wordpress主题(Mobile theme)
    一个强大专业的响应式jQuery幻灯效果插件:Royal Slider
    超过30个超棒的漂亮iphone 4s墙纸
    帮助你自动生成已经过去的时间的jQuery插件 Smart Time Ago
    分享20个响应式web设计的必备jQuery插件
    2012年度最新免费web开发设计资源荟萃
    myEclipse 下载
    extjs 配置与表格使用
    mysql 4.0.26 安装流程
    spring+ehcache 实现原理
  • 原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/9160921.html
Copyright © 2011-2022 走看看