Par de zócalos del marco de Android

breve descripción

En Linux, socketpairla función se puede usar para crear un par de AF_UNIXsockets de dominio de comunicación interconectados, donde un socket se puede usar para leer y el otro socket se puede usar para escribir. Este par de sockets se puede utilizar para la comunicación entre procesos (IPC) dentro del mismo proceso.

Estos son socketpairlos pasos básicos para crear un par de sockets usando una función:

  1. Incluir archivos de encabezado sys/types.hy sys/socket.h.unistd.h

  2. Declare una matriz de longitud 2 como parámetro del descriptor de socket.

  3. Llame socketpaira la función , pasándole la matriz de descriptores de socket como argumento. El prototipo de función es:

    int socketpair(int domain, int type, int protocol, int sv[2]);
    
    • domainEl parámetro especifica el dominio de comunicación, normalmente establecido en AF_UNIX.
    • typeEl parámetro especifica el tipo de socket y se puede establecer en SOCK_STREAMo SOCK_DGRAM.
    • protocolEl parámetro generalmente se establece en 0, lo que significa que se usa el protocolo predeterminado.
    • svEl parámetro es una matriz de enteros de longitud 2, que se utiliza para guardar el descriptor de socket creado.
  4. svComunicación entre procesos utilizando descriptores de socket en una matriz.

ejemplo de linux

Aquí hay socketpairun ejemplo simple basado en pasar datos entre procesos padre e hijo:

#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;
}

El programa primero llama socketpaira la función para crear un par de sockets de dominio UNIX, que se almacenan sockfden la matriz. Luego, el programa llama forka la función para crear un proceso secundario. En el proceso hijo, cierra sockfd[0], luego escribe un mensaje sockfd[1]y cierra sockfd[1]. En el proceso principal, se cierra sockfd[1], luego lee un sockfd[0]mensaje , lo imprime en la salida estándar y finalmente se cierra sockfd[0].

Cuando este programa se ejecuta, crea un proceso secundario, el proceso secundario envía un mensaje al proceso principal, el proceso principal recibe el mensaje y lo imprime:

Parent: received message from child: Hello, parent!

Ejemplo de marco de trabajo de Android

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.cppEs el archivo de implementación de BitTubela clase .

EntradaTransporte

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

En el sistema de entrada de Android, InputTransportuse socketpairla función para crear un par de sockets locales full-duplex (sockets) para pasar eventos de entrada entre el programa de aplicación y el controlador. Uno de los zócalos se usa para enviar eventos de entrada al controlador y el otro zócalo se usa para recibir eventos de entrada del controlador. De esta forma, InputTransportpuede enviar eventos de entrada al controlador y recibir eventos de entrada generados por el controlador.

Supongo que te gusta

Origin blog.csdn.net/weixin_45767368/article/details/129195609
Recomendado
Clasificación