美文网首页
socketpair的用法

socketpair的用法

作者: 棒棒0_0 | 来源:发表于2021-10-05 12:02 被阅读0次

    在android的input系统中,inputDispatcher与APP是通过socket进行通信的,也就是InputDispatcher通过::send把InputMessage写入socket,APP通过::recv读出InputMessage。
    那么,我们来梳理一下socket是如何建立的,首先看InputTransport.cpp中的代码

    status_t InputChannel::openInputChannelPair(const std::string& name,
            sp<InputChannel>& outServerChannel, sp<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=%d",
                    name.c_str(), errno);
            outServerChannel.clear();
            outClientChannel.clear();
            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));
    
        std::string serverChannelName = name;
        serverChannelName += " (server)";
        outServerChannel = new InputChannel(serverChannelName, sockets[0]);
    
        std::string clientChannelName = name;
        clientChannelName += " (client)";
        outClientChannel = new InputChannel(clientChannelName, sockets[1]);
        return OK;
    }
    

    从代码中看,我们创建socket用哪个的socketpair()函数
    socketpair()函数的声明:

    #include <sys/types.h>
    #include <sys/socket.h>
    int socketpair(int d, int type, int protocol, int sv[2]);
    

    1.socketpair()函数用于创建一对无名的,相互连接的套接字。
    2.如果函数创建成功,则返回0,创建好的套接字分别是sv[0]和sv[1];否则返回-1,错误码保存在errno中。
    3.这对套接字可以用于全双工通信,每个套接字既可以读也可以写。比如:我们可以往sv[0]中写,从sv[1]中读,我们也可以往sv[1]中写,从sv[0]中读。
    4.如果往一个套接字中写入后,再从该套接字读时,则会阻塞。只能在另一个套接字中读。
    5.读写操作可以位于同一个进程,也可以位于不同的进程,如父子进程,如果父子进程时,一个进程用来读,一个进程用来写。因为文件描述符sv[0]和sv[1]是进程共享的,所以读的进程要关闭写的描述符,反之,写的进程要关闭读的描述符。

    示例代码:

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <error.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <stdlib.h>
    
    const char* str = "SOCKET PAIR TEST.";
    
    int main(int argc, char* argv[])
    {
        char buf[128] = {0x00};
        int socket_pair[2];
        pid_t pid;
    
        if(socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair) == -1)
        {
            printf("Error, socketpair create failed, errno(%d):%s\n", errno, strerror(errno));
            return EXIT_FAILURE;
        }
    
        int size = write(socket_pair[0], str, strlen(str));
        read(socket_pair[1], buf, size);
        printf("read buf:%s", buf);
        return EXIT_SUCCESS;
    }
    
    
    #include <stdio.h> 
    #include <string.h> 
    #include <unistd.h> 
    #include <sys/types.h> 
    #include <error.h> 
    #include <errno.h> 
    #include <sys/socket.h> 
    #include <stdlib.h> 
     
    const char* str = "SOCKET PAIR TEST.";
     
    int main(int argc, char* argv[]){
        char buf[128] = {0};
        int socket_pair[2]; 
        pid_t pid; 
     
        if(socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair) == -1 ) { 
            printf("Error, socketpair create failed, errno(%d): %s\n", errno, strerror(errno));
            return EXIT_FAILURE; 
        } 
     
        pid = fork();
        if(pid < 0) {
            printf("Error, fork failed, errno(%d): %s\n", errno, strerror(errno));
            return EXIT_FAILURE;
        } else if(pid > 0) {
            //关闭另外一个套接字
            close(socket_pair[1]);
            int size = write(socket_pair[0], str, strlen(str));
            printf("Write success, pid: %d\n", getpid());
     
        } else if(pid == 0) {
            //关闭另外一个套接字
            close(socket_pair[0]);
            read(socket_pair[1], buf, sizeof(buf));        
            printf("Read result: %s, pid: %d\n",buf, getpid());
        }
     
        for(;;) {
            sleep(1);
        }
     
        return EXIT_SUCCESS;    
    } 
    

    相关文章

      网友评论

          本文标题:socketpair的用法

          本文链接:https://www.haomeiwen.com/subject/fwfgnltx.html