android socket双向,Android中socketpair双向通信详解
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双向通信详解相关推荐
- [Android] DiffUtil在RecyclerView中的使用详解
概述 DiffUtil是recyclerview support library v7 24.2.0版本中新增的类,根据Google官方文档的介绍,DiffUtil的作用是比较两个数据列表并能计算出一 ...
- android调webview的方法,Android中的WebView详解
Android中的WebView详解 WebView详解 基本用法 布局文件配置WebView android:id="@+id/wv_news_detail" android:l ...
- Android 7.1.1 Dialer中通话记录显示详解
这两天在看通话记录相关问题,顺便跟踪了Dialer中的通话记录是怎么显示出来的,在这和大家分享下.当有来电或去电时,calllog会被插入到calllog.db的数据中去,具体可以参考<Andr ...
- Android 中malloc_debug 原理详解
版本基于:Android R 关联博文: Android 中malloc_debug 使用详解 0. 前言 最近上项目中遇到一个native 可能内存泄漏的问题,曾考虑使用HWASAN,但这个工具是针 ...
- Android设置中“强行停止”详解
Android设置中"强行停止"详解 最近工作上遇到了广播接受不到的问题,查看了<Android 开发艺术探索>一书中关于广播的发送和接受的章节(P356-P362). ...
- Android中mesure过程详解 (结合Android 4.0.4 最新源码)
如何遍历并绘制View树?之前的文章Android中invalidate() 函数详解(结合Android 4.0.4 最新源码)中提到invalidate()最后会发起一个View树遍历的请求,并通 ...
- Android中layout过程详解 (结合Android 4.0.4 最新源码)
上一篇文章Android中mesure过程详解 (结合Android 4.0.4 最新源码)介绍了View树的measure过程,相对与measure过程,本文介绍的layout过程要简单多了,正如l ...
- Android JNI使用方法,JNI机制详解
Android JNI使用方法,JNI机制详解 JNI的出现使得开发者既可以利用Java语言跨平台.类库丰 富.开发便捷等特点,又可以利用Native语言的高效. JNI是JVM实现中的一部分,因此N ...
- Android进阶笔记:Messenger源码详解
Messenger可以理解为一个是用于发送消息的一个类用法也很多,这里主要分析一下再跨进程的情况下Messenger的实现流程与源码分析.相信结合前面两篇关于aidl解析文章能够更好的对aidl有一个 ...
最新文章
- 敏捷开发一千零一问系列之四:优先级排错怎么办?
- CCNA--点对点协议(PPP)
- vectorobserver obs是做什么_带着色碳纤维主体的OBS雪佛兰皮卡
- 洛谷P2483 Bzoj1975 [SDOI2010]魔法猪学院
- 日期 java cal,日期系列教材 (三)- 如何使用Java的Calendar类
- 【jQuery】smartMenu右键自定义上下文菜单插件(似web QQ)
- 【JAVA】接口中的default和static方法
- eslint配置及rule解释
- 开机后系统时间被恶意修改
- C语言项目大作业万历年,用C语言编写万历,详细代码.doc
- 祝贺泰山JDK8开源
- matlab 2014
- python颜色过渡
- 计算机网络期末总结复习(全)
- xz1刷Android10,索尼xz1国行版安卓9.0固件
- 关于最近阿里内部员工抢月饼事件引发的js程序扩展
- 消灭Bug,开发者不可不知的几款Bug探索测试神器。
- 回溯算法之迷宫问题(Maze)
- 关于 draw.io 矢量图 SVG 导出的研究
- 微信二维码使用及配置