当前位置: 首页 > news >正文

Android framework socketpair

简述

在Linux中,socketpair函数可以用于创建一对相互连接的、通信域为AF_UNIX的套接字,其中一个套接字可用于读取,另一个套接字可用于写入。可以使用这对套接字在同一进程内进行进程间通信(IPC)。

以下是使用socketpair函数创建套接字对的基本步骤:

  1. 包含头文件 sys/types.hsys/socket.hunistd.h

  2. 声明一个长度为2的数组作为套接字描述符的参数。

  3. 调用 socketpair 函数,并将套接字描述符数组作为参数传递给它。函数原型为:

    int socketpair(int domain, int type, int protocol, int sv[2]);
    
    • domain参数指定通信域,通常设置为AF_UNIX。
    • type参数指定套接字类型,可以设置为SOCK_STREAMSOCK_DGRAM
    • protocol参数通常设置为0,表示使用默认协议。
    • sv参数是一个长度为2的整数数组,用于保存创建的套接字描述符。
  4. 使用sv数组中的套接字描述符进行进程间通信。

Linux举例

下面是一个基于 socketpair 的简单例子,用于在父子进程之间传递数据:

#include <unistd.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>int main() {int sockfd[2];char buf[1024];pid_t pid;if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) {perror("socketpair");return 1;}if ((pid = fork()) == -1) {perror("fork");return 1;}if (pid == 0) {  // 子进程close(sockfd[0]);char msg[] = "Hello, parent!";if (write(sockfd[1], msg, strlen(msg)) < 0) {perror("write");return 1;}close(sockfd[1]);} else {  // 父进程close(sockfd[1]);int n = read(sockfd[0], buf, sizeof(buf));if (n < 0) {perror("read");return 1;}printf("Parent: received message from child: %s\n", buf);close(sockfd[0]);}return 0;
}

该程序首先调用 socketpair 函数创建一对 UNIX 域套接字,存储在 sockfd 数组中。然后,程序调用 fork 函数创建一个子进程。在子进程中,它关闭 sockfd[0],然后将一条消息写入 sockfd[1],然后关闭 sockfd[1]。在父进程中,它关闭 sockfd[1],然后从 sockfd[0] 中读取一条消息,并将其打印到标准输出中,最后关闭 sockfd[0]

当该程序运行时,它会创建一个子进程,子进程向父进程发送一条消息,父进程接收到该消息并将其打印出来:

Parent: received message from child: Hello, parent!

Android framework 举例

android-12.0.0_r28/frameworks/native/libs/sensor/BitTube.cpp

BitTube
void BitTube::init(size_t rcvbuf, size_t sndbuf) {int sockets[2];if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {size_t size = DEFAULT_SOCKET_BUFFER_SIZE;setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));// sine we don't use the "return channel", we keep it small...setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));fcntl(sockets[0], F_SETFL, O_NONBLOCK);fcntl(sockets[1], F_SETFL, O_NONBLOCK);mReceiveFd = sockets[0];mSendFd = sockets[1];} else {mReceiveFd = -errno;ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));}
}

BitTube.cpp 是 Android 中传感器服务和传感器驱动程序之间通信使用的 BitTube 类的实现文件。

InputTransport

android-12.0.0_r28/frameworks/native/libs/input/InputTransport.cpp

status_t InputChannel::openInputChannelPair(const std::string& name,std::unique_ptr<InputChannel>& outServerChannel,std::unique_ptr<InputChannel>& outClientChannel) {int sockets[2];if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {status_t result = -errno;ALOGE("channel '%s' ~ Could not create socket pair.  errno=%s(%d)", name.c_str(),strerror(errno), errno);outServerChannel.reset();outClientChannel.reset();return result;}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));sp<IBinder> token = new BBinder();std::string serverChannelName = name + " (server)";android::base::unique_fd serverFd(sockets[0]);outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd), token);std::string clientChannelName = name + " (client)";android::base::unique_fd clientFd(sockets[1]);outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd), token);return OK;
}

在 Android Input 系统中,InputTransport 使用 socketpair 函数创建一对全双工的本地套接字(socket),用于在应用程序和驱动程序之间传递输入事件。其中一个套接字用于向驱动程序发送输入事件,另一个套接字用于接收来自驱动程序的输入事件。通过这种方式,InputTransport 可以将输入事件发送到驱动程序,并接收驱动程序生成的输入事件。

http://www.lryc.cn/news/18859.html

相关文章:

  • 腾讯在海外游戏和短视频广告领域的新增长机会
  • 查找该学号学生的成绩。
  • 为Webpack5项目引入Buffer Polyfill
  • 【人工智能 AI 】您可以使用机器人流程自动化 (RPA) 实现自动化的 10 个业务流程:Robotic Process Automation (RPA)
  • VMware ESXi 8.0b - 领先的裸机 Hypervisor (Dell HPE Custom Image update)
  • Java:SpringBoot 整合Spring-Retry实现错误重试
  • MyBatis学习笔记(二) —— 搭建MyBatis项目
  • linux服务器上Docker中安装jenkins
  • 自考都有哪些科目?怎么搭配报考?
  • HIVE --- 高级查询
  • 【手撕源码】vue2.x双向数据绑定原理
  • Allegro如何显示层叠Options和Find操作界面
  • 【数据结构】双向链表
  • Editor工具开发基础三:自定义组件菜单拓展 CustomEditor
  • 拒绝摆烂!神仙网站Python自学,一路从入门闯到最后,边学边玩
  • Linux基础命令-locate快速查找文件
  • 揭穿数据分析的六大谎言
  • LinkSLA智能运维技术派-Redis的监控
  • Hugging face 模型微调学习:T5-base的微调
  • JavaScript 测试 Prototype
  • pnpm / yarn / npm管理依赖包
  • 注意力机制详解系列(一):注意力机制概述
  • 搜索引擎 Elasticsearch 的三大坑
  • 运营级手机直播平台源码 短视频直播带货APP源码
  • http/HTTPS相关的一些知识
  • MySQL高可用 集群(MHA)
  • 【JavaScript速成之路】JavaScript运算符
  • 计网个人作业05
  • 码匠 × OpenAI :快速生成 SQL 语句,提升开发效率!
  • 电脑显示屏不亮但是主机已开机?5种原因以及解决方案