Android很多地方会涉及到进程间的通信,比如输入系统,那么进程间通信会涉及哪些内容呢?

1、进程:负责读取和分发事件

2、应用程序:负责处理输入事件

上面这两个进程会涉及哪些双向通信呢:

1.进程会发送输入事件

2.应用程序会告知事件处理完或APP已关闭

这里大家可能会有疑惑,binder系统能否实现上面所说的双向通信呢?

答案是不行,binder分为server和client,每次都由client主动发出请求,server收到请求后进行答复,这样的缺点就是每次请求只能单方发起,server不能主动发送数据给client,这样自然不能称为双向通信。

所以这里引入一个新的方法,叫“socketpair”

APP通过socketpair调用得到两个文件句柄,假设这两个文件句柄是fd1和fd2,这两个文件都对应有两个缓冲区(send_buf、rcv_buf),当某个进程或线程通过fd1写到他的send_buf的时候,内核里面的socket就会把send_buf里面的数据写到fd2的rcv_buf里面,另外一个线程或进程就可以读取fd2得到那些数据了,相反同理。

但是它也有缺点:由于是通过创建文件句柄来访问句柄实现的通信,那么谁可以看到这个句柄呢,只有当前APP创建出来的线程或它创建出来的子进程才能看到这些文件句柄,所以只适用于线程间通信,或者具有亲缘关系(父子进程)的进程间通信。

那么如果想使用socketpair来实现任意间的进程间的双向通信怎么办?

假设现在有APP1和APP2,这两个APP想进行任意间的进程通信,那么APP2需要得到APP1的fd2才行,怎么得到呢?可以通过binder通信,把fd2传给APP2,当然在APP2里面它就变为fd3了,这样这个任意的进程APP2就可以通过socketpair来进行通信了。这篇暂不讲解binder的实现方式

下面讲解一下“Socketpair”的程序及使用:

#include

#include

#include

#include /* See NOTES */

#include

#define SOCKET_BUFFER_SIZE (32768U)

/* 参考:

* frameworks\native\libs\input\InputTransport.cpp

*/

/* 线程1函数实现 */

void *function_thread1 (void *arg)

{

int fd = (int)arg;/* 把文件句柄转换出来 */

char buf[500];

int len;

int cnt = 0;

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);

/* 延时5秒钟 */

sleep(5);

}

return NULL;

}

int main(int argc, char **argv)

{

int sockets[2];

/* 使用 socketpair 得到两个文件句柄到数组sockets */

socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);

/* 设置缓冲区, 每个文件句柄对应两个缓冲区,两个文件对应四个 */

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(thread1),并把文件句柄sockets[1]传给子线程thread1 */

pthread_t threadID;

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

char buf[500];

int len;

int cnt = 0;

int fd = sockets[0];/* 当前main函数的文件句柄是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);

}

}

程序非常简单,先是使用socketpair得到两个文件句柄并设置发送接收缓冲区,然后创建另一个线程,在线程中通过文件句柄读写数据到main线程中,mian也执行同样的操作实现双向通信。

测试验证:

检查是否存在这两个线程:

我们还可以修改程序,让应用程序fork出一个子进程,然后让父子进程通过socketpair来实现双向通信,比较简单,这里就不细讲了。

由于socekpair只适用于线程间通信,或者具有亲缘关系,如果想实现任意的两个进程间的双向通信就需要使用binder系统把fd传给另一个进程,这里简单说下过程,如下:

使用binder传输文件句柄:

假设APP1,open某个文件句柄得到fd1

通过binder驱动根据fd1得到file结构体,即files->fdt->fd[fd1]

从APP2的files->fdt->fd中取出一个空项,假设是fd2,让fd2指向fd1的file结构体,即files->fdt->fd[fd2]=file

之后APP1可以通过fd1,APP2可以通过fd2访问同一个文件了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

android socket双向,Android中socketpair双向通信详解相关推荐

  1. [Android] DiffUtil在RecyclerView中的使用详解

    概述 DiffUtil是recyclerview support library v7 24.2.0版本中新增的类,根据Google官方文档的介绍,DiffUtil的作用是比较两个数据列表并能计算出一 ...

  2. android调webview的方法,Android中的WebView详解

    Android中的WebView详解 WebView详解 基本用法 布局文件配置WebView android:id="@+id/wv_news_detail" android:l ...

  3. Android 7.1.1 Dialer中通话记录显示详解

    这两天在看通话记录相关问题,顺便跟踪了Dialer中的通话记录是怎么显示出来的,在这和大家分享下.当有来电或去电时,calllog会被插入到calllog.db的数据中去,具体可以参考<Andr ...

  4. Android 中malloc_debug 原理详解

    版本基于:Android R 关联博文: Android 中malloc_debug 使用详解 0. 前言 最近上项目中遇到一个native 可能内存泄漏的问题,曾考虑使用HWASAN,但这个工具是针 ...

  5. Android设置中“强行停止”详解

    Android设置中"强行停止"详解 最近工作上遇到了广播接受不到的问题,查看了<Android 开发艺术探索>一书中关于广播的发送和接受的章节(P356-P362). ...

  6. Android中mesure过程详解 (结合Android 4.0.4 最新源码)

    如何遍历并绘制View树?之前的文章Android中invalidate() 函数详解(结合Android 4.0.4 最新源码)中提到invalidate()最后会发起一个View树遍历的请求,并通 ...

  7. Android中layout过程详解 (结合Android 4.0.4 最新源码)

    上一篇文章Android中mesure过程详解 (结合Android 4.0.4 最新源码)介绍了View树的measure过程,相对与measure过程,本文介绍的layout过程要简单多了,正如l ...

  8. Android JNI使用方法,JNI机制详解

    Android JNI使用方法,JNI机制详解 JNI的出现使得开发者既可以利用Java语言跨平台.类库丰 富.开发便捷等特点,又可以利用Native语言的高效. JNI是JVM实现中的一部分,因此N ...

  9. Android进阶笔记:Messenger源码详解

    Messenger可以理解为一个是用于发送消息的一个类用法也很多,这里主要分析一下再跨进程的情况下Messenger的实现流程与源码分析.相信结合前面两篇关于aidl解析文章能够更好的对aidl有一个 ...

最新文章

  1. 敏捷开发一千零一问系列之四:优先级排错怎么办?
  2. CCNA--点对点协议(PPP)
  3. vectorobserver obs是做什么_带着色碳纤维主体的OBS雪佛兰皮卡
  4. 洛谷P2483 Bzoj1975 [SDOI2010]魔法猪学院
  5. 日期 java cal,日期系列教材 (三)- 如何使用Java的Calendar类
  6. 【jQuery】smartMenu右键自定义上下文菜单插件(似web QQ)
  7. 【JAVA】接口中的default和static方法
  8. eslint配置及rule解释
  9. 开机后系统时间被恶意修改
  10. C语言项目大作业万历年,用C语言编写万历,详细代码.doc
  11. 祝贺泰山JDK8开源
  12. matlab 2014
  13. python颜色过渡
  14. 计算机网络期末总结复习(全)
  15. xz1刷Android10,索尼xz1国行版安卓9.0固件
  16. 关于最近阿里内部员工抢月饼事件引发的js程序扩展
  17. 消灭Bug,开发者不可不知的几款Bug探索测试神器。
  18. 回溯算法之迷宫问题(Maze)
  19. 关于 draw.io 矢量图 SVG 导出的研究
  20. 微信二维码使用及配置

热门文章

  1. 谈加薪,真不是涨点钱那么简单
  2. python函数中经常出现的*args和**kw是什么?
  3. 男人有必要学会做饭,做家务吗?
  4. Qt学习笔记之--Qt内置图标一览表
  5. IndexError: list index out of range的错误原因及解决方案
  6. 降噪蓝牙耳机哪个牌子好?最便宜的蓝牙主动降噪耳机推荐
  7. php encrypt加密和解密,php中关于openssl_encrypt的加密和解密
  8. 神级程序员都用什么工具?2020 年度开发工具 Top 100
  9. js slice 假分页
  10. 近代数学学派知多少?