Linux内核之双向通信Socketpair

双向通信(socketpair)
socketpair 函数
功能:创建一个全双工的流管道
原型 int socketpair(int domain, int type, int protocol, int sv[2]);
参数:
domain: 协议家族
type: 套接字类型
protocol: 协议类型
sv: 返回套接字对
返回值:成功返回0;失败返回-1
实际上socketpair 函数跟pipe 函数是类似的,也只能在同个主机上具有亲缘关系的进程间通信,但pipe 创建的匿名管道是半双工的,而socketpair 可以认为是创建一个全双工的管道。

缺点:只适用于线程间,或者具有亲缘关系的进程间

实现一个进程间两个线程的相互通信:

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>

#define SOCKET_BUFFER_SIZE (32768U)


/* 参考: * frameworks\native\libs\input\InputTransport.cpp */

void *function_thread1 (void *arg)
{
    int fd = (int)arg; //Garmen:将传入的socket[0]进行转换
    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);

        sleep(5);
    }

    return NULL;
}


int main(int argc, char **argv)
{
    int sockets[2];

    socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);

    /*frameworks\native\libs\input\InputTransport.cpp (socketpair)*/
    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 */
    pthread_t threadID;
    pthread_create(&threadID, NULL, function_thread1, (void *)sockets[1]);


    char buf[500];
    int len;
    int cnt = 0;
    int fd = 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);
    }
}

参考代码:
frameworks\native\libs\input\InputTransport.cpp (socketpair)
调用过程
WindowManagerService.java
InputChannel.openInputChannelPair(name)
nativeOpenInputChannelPair(name);
android_view_InputChannel_nativeOpenInputChannelPair
InputChannel::openInputChannelPair (InputTransport.cpp)

测试:
gcc -o socketpair socketpair.c -lpthread
./socketpair

你可能感兴趣的:(linux,kernel)