socketpair通信
1、线程间通信(参考安卓源码InputTransport.cpp)
#include <pthread.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h> static const size_t SOCKET_BUFFER_SIZE = * ; void *pthread_1(void *arg)
{
int fd = *((int *)arg);
char buf[];
int len;
int cnt = ; while () {
len = sprintf(buf, "hello, main pthread, cnt = %d", cnt++);
write(fd, buf, len); len = read(fd, buf, );
buf[len] = '\0';
printf("%s\n", buf);
sleep();
}
return NULL;
} int main(int argc, char **argv)
{
int sockets[];
pthread_t thread_id;
if (socketpair(AF_UNIX, SOCK_SEQPACKET, , sockets)) {
printf("socketpair error\n");
return -;
}
int bufferSize = SOCKET_BUFFER_SIZE;
/* 创建4个buff, sockets[0]的发送buff和接收buff; sockets[1]的发送buff和接收buff*/
setsockopt(sockets[], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
int res = pthread_create(&thread_id, NULL, pthread_1, (void *)(&sockets[]));
if (res) {
printf("pthread_create error\n");
return -;
}
int fd = sockets[];
char buf[];
int len;
int cnt = ; while () {
len = sprintf(buf, "hello, pthread1, cnt = %d", cnt++);
write(fd, buf, len); //将buf中的内容通过fd句柄发送到snd buff len = read(fd, buf, ); //通过读fd中的rcv buff, 将内容读到buf中,然后打印出来
buf[len] = '\0';
printf("%s\n", buf);
sleep();
}
return ;
}
打印信息:
再打开一个终端查看进程:ps -A 查看socketpair的pid为6065
cd /proc/6065
ls task
2、父子进程间通信
需要注意的是fd == 0是子进程,fd > 0 是父进程
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h> static const size_t SOCKET_BUFFER_SIZE = * ; int main(int argc, char **argv)
{
int sockets[];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, , sockets)) {
printf("socketpair error\n");
return -;
}
int bufferSize = SOCKET_BUFFER_SIZE;
setsockopt(sockets[], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
pid_t fd = fork();if (fd == ) {
/* 子进程 */
int fd = sockets[];
char buf[];
int len;
int cnt = ;
while () {
len = sprintf(buf, "hello, father pid, cnt = %d", cnt++);
write(fd, buf, len); len = read(fd, buf, );
buf[len] = '\0';
printf("%s\n", buf);
sleep();
}
}
if (fd > ) {
/* 父进程 */
int fd = sockets[];
char buf[];
int len;
int cnt = ;
while () {
len = sprintf(buf, "hello, child pid, cnt = %d", cnt++);
write(fd, buf, len); len = read(fd, buf, );
buf[len] = '\0';
printf("%s\n", buf);
sleep();
} } return ;
}
运行结果:
查看进程:ps -A 有2个名为fork的进程
3、使用binder传递文件句柄,实现进程间通信
4、看得出来socketpair实现了进程或线程间的双全工通信
而管道一般是半全工通信,要双全工就得创建2个管道
#include <unistd.h>
#include <stdio.h> int main(int argc, char **argv)
{ int fd[]; //fd[0]是读,fd[1]是写
int fd2[];
int res = pipe(fd);
if (res) {
printf("create pipe error\n");
return -;
}
res = pipe(fd2);
if (res) {
printf("create pipe2 error\n");
return -;
}
pid_t pid = fork();
if (pid > ) {
char buf[];
int len;
while () {
len = sprintf(buf, "hello my child!");
buf[len] = '\0';
write(fd[], buf, len);
len = read(fd2[], buf, );
buf[len] = '\0';
printf("%s\n", buf);
sleep();
}
}
else if (pid == ) {char buf[];
int len;
while () {
len = read(fd[], buf, );
buf[len] = '\0';
printf("%s\n", buf);
len = sprintf(buf, "hello my father!");
buf[len] = '\0';
write(fd2[], buf, len);
sleep();
} } return ;
}
同样pipe也可以用于线程间通信:
#include <unistd.h>
#include <stdio.h>
#include <pthread.h> struct pipe_rw {
int fd_r;
int fd_w;
}; void *thread_handle(void *arg)
{
struct pipe_rw *pPipeRw = (struct pipe_rw *)arg;
char buf[];
int len;
while () {
len = read(pPipeRw->fd_r, buf, );
buf[len] = '\0';
printf("%s\n", buf);
len = sprintf(buf, "hello my father");
buf[len] = '\0';
write(pPipeRw->fd_w, buf, len);
sleep();
}
} int main(int argc, char **argv)
{ int fd[]; //fd[0]是读,fd[1]是写
int fd2[];
int res = pipe(fd);
if (res) {
printf("create pipe error\n");
return -;
}
res = pipe(fd2);
if (res) {
printf("create pipe2 error\n");
return -;
}
pthread_t thread;
struct pipe_rw pipe_arg;
pipe_arg.fd_r = fd[];
pipe_arg.fd_w = fd2[];
pthread_create(&thread, NULL, thread_handle, &pipe_arg);
char buf[];
int len;
while () {
len = sprintf(buf, "hello my child");
buf[len] = '\0';
write(fd[], buf, len);
len = read(fd2[], buf, );
buf[len] = '\0';
printf("%s\n", buf);
sleep();
} return ;
}
命名管道:
write:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h> #define PATH "./myfifo" int main(int argc, char **argv)
{
int res = mkfifo(PATH, |S_IFIFO); //在当前目录下创建一个名为myfifo的管道
if (res) {
printf("create named pipe error\n");
return -;
}
int fd = open(PATH, O_WRONLY); //命名管道是可以直接open的
if (fd < ) {
printf("open %s error\n", PATH);
return -;
}
char buf[];
int len;
len = sprintf(buf, "hello world");
while () {
write(fd, buf, len);
sleep();
}
close(fd);
return ;
}
read:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h> #define PATH "./myfifo" int main(int argc, char **argv)
{
int fd = open(PATH, O_RDONLY);
if (fd < ) {
printf("open %s error\n", PATH);
return -;
}
char buf[];
int len;
while () {
len = read(fd, buf, 512);
buf[len] = '\0';
printf("%s\n", buf);
}
close(fd);
return ;
}
socketpair通信的更多相关文章
- linux 单机跨进程通信
一般来说通过网络通信(比如tcp,udp)或者共享内存的方式肯定可以实现跨进程通信,但现在这里要说的是比较偏但实用的几个方法:利用unix域通信(普通网络连接),利用unix域通信(socketpai ...
- UNP学习 Unix域协议
Unix域协议并不是一个实际的协议族,它只是在同一台主机上进行客户-服务器通信时,使用与在不同主机上的客户和服务器间通信时相同的API的一种方法. 当客户和服务器在同一台主机上时,Unix域协议是这套 ...
- socketpair创建双向通信的管道(全双工通信)
Linux下socketpair介绍: socketpair创建了一对无名的套接字描述符(只能在AF_UNIX域中使用),描述符存储于一个二元数组,例如sv[2] .这对套接字可以进行双工通信,每一个 ...
- 线程之间的通信socketpair【学习笔记】【原创】
平台信息:内核:linux3.1.0系统:android5.0平台:tiny4412 作者:庄泽彬(欢迎转载,请注明作者) 说明: 韦老师的安卓视频学习笔记 一.在一个进程中多个线程如何进行通信,主要 ...
- ZeroMQ(java)之I/O线程的实现与组件间的通信
算是开始读ZeroMQ(java)的代码实现了吧,现在有了一个大体的了解,看起来实现是比较的干净的,抽象什么的不算复杂... 这里先来看看它的I/O线程的实现吧,顺带看看是如何实现组件的通信的.... ...
- socketpair理解
转载:http://liulixiaoyao.blog.51cto.com/1361095/533469/ 今天跟人谈到socketpair的问题,晚上回来写了个程序验证下自己的猜测! 先说说我的理解 ...
- 【Chromium中文文档】跨进程通信 (IPC)
跨进程通信 (IPC) 转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/I ...
- UNIX网络编程——UNIX域套接字编程和socketpair 函数
一.UNIX Domain Socket IPC socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络soc ...
- 输入系统:进程间双向通信(socketpair+binder)
一.双向通信(socketpair) socketpair()函数用于创建一对无名的.相互连接的套接子,如果函数成功,则返回0,创建好的套接字分别是sv[0]和sv[1]:否则返回-1,错误码保存于e ...
随机推荐
- 教你如何封装异步网络连接NSURLConnection实现带有百分比的下载
教你如何封装异步网络连接NSURLConnection实现带有百分比的下载 注:本教程需要你对block有着较为深刻的理解,且对如何封装对象有着一些经验. 也许你已经用惯了AFNetworking2. ...
- Spark Worker原理和源码剖析解密:Worker工作流程图、Worker启动Driver源码解密、Worker启动Executor源码解密等
本课主题 Spark Worker 原理 Worker 启动 Driver 源码鉴赏 Worker 启动 Executor 源码鉴赏 Worker 与 Master 的交互关系 Spark Worke ...
- js中公有方法、特权方法、静态方法
1.公有属性和公有方法 1 2 3 4 5 6 7 8 9 function User(name,age){ this.name = name;//公有属性 this.age = age; } ...
- June 19th 2017 Week 25th Monday
Everyone is dissatisfied with his own fortune. 人对自己的命运总是感到不满足. We always want more, even when we hav ...
- ERROR Review:Unsupported major.minor version 52.0
最近将AS从2.1.2升级至2.2版本后,项目编译报出了如下错误: java.lang.UnsupportedClassVersionError: com/android/build/gradle/L ...
- RabbitMQ的事件总线
RabbitMQ的事件总线 在上文中,我们讨论了事件处理器中对象生命周期的问题,在进入新的讨论之前,首先让我们总结一下,我们已经实现了哪些内容.下面的类图描述了我们已经实现的组件及其之间的关系,貌似系 ...
- 关于Java中的反射的一个简单使用
把以前在其他地方的技术文章重新整理一遍, 方便自己回忆, 也方便他人借鉴. 刚工作的时候发过这么一段代码: package cn.com.hanbinit.test; import java.lang ...
- Spring Framework5.0 学习(4)—— Bean的命名id和name区别
Spring中Bean的命名 1.每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一: 2.可以不指定id属性,只指定全限定类名,如: & ...
- 洛谷 P4321 【随机漫游】
题目大意 给出\(n(n\leq 18)\)个点的无向连通图,\(m(m\leq 10^5)\)次询问.每次询问给出一个点集和一个起点\(s\),询问从\(s\)出发,经过这个点集中的每一个点至少一次 ...
- Core Animation Manages Your App’s Content
Core Animation 是对现有图片的操作函数. https://developer.apple.com/library/content/documentation/Cocoa/Conceptu ...