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