Linux内核之双向通信Socketpair

来源:互联网 发布:成年后不喜欢读书 知乎 编辑:程序博客网 时间:2024/06/08 17:12

双向通信(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