礼仪策划网站建设,网站建设报价单 文库,宁德市教育局,wordpress主题源文件简述
在Linux中#xff0c;socketpair函数可以用于创建一对相互连接的、通信域为AF_UNIX的套接字#xff0c;其中一个套接字可用于读取#xff0c;另一个套接字可用于写入。可以使用这对套接字在同一进程内进行进程间通信#xff08;IPC#xff09;。
以下是使用socketp…简述
在Linux中socketpair函数可以用于创建一对相互连接的、通信域为AF_UNIX的套接字其中一个套接字可用于读取另一个套接字可用于写入。可以使用这对套接字在同一进程内进行进程间通信IPC。
以下是使用socketpair函数创建套接字对的基本步骤 包含头文件 sys/types.h、sys/socket.h 和 unistd.h。 声明一个长度为2的数组作为套接字描述符的参数。 调用 socketpair 函数并将套接字描述符数组作为参数传递给它。函数原型为 int socketpair(int domain, int type, int protocol, int sv[2]);domain参数指定通信域通常设置为AF_UNIX。type参数指定套接字类型可以设置为SOCK_STREAM或SOCK_DGRAM。protocol参数通常设置为0表示使用默认协议。sv参数是一个长度为2的整数数组用于保存创建的套接字描述符。 使用sv数组中的套接字描述符进行进程间通信。
Linux举例
下面是一个基于 socketpair 的简单例子用于在父子进程之间传递数据
#include unistd.h
#include sys/socket.h
#include stdio.h
#include string.hint 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 dont 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_ptrInputChannel outServerChannel,std::unique_ptrInputChannel 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));spIBinder 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 可以将输入事件发送到驱动程序并接收驱动程序生成的输入事件。