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 ...
随机推荐
- SQL Server ->> 深入探讨SQL Server 2016新特性之 --- Row-Level Security(行级别安全控制)
SQL Server 2016 CPT3中包含了一个新特性叫Row Level Security(RLS),允许数据库管理员根据业务需要依据客户端执行脚本的一些特性控制客户端能够访问的数据行,比如,我 ...
- Microsoft Office ->> 完整卸载Office 2007
今天用GHOST安装了Windows 8.1,结果发现预装了Office 2007,而且这个GHOST系统的Office 2007还不是很正规的安装手法安装的.它没有在注册表中注册.在打开控制面板后发 ...
- mongodb时间点备份恢复
1:创建测试数据 > use maxiangqian switched to db maxiangqian "}) WriteResult({ "nInserted" ...
- C# 使用 Invoke 实现函数的白盒 UT 测试
公有方法可以直接调用,但是一些非公开的方法,在覆盖率测试的时候也需要覆盖,可以使用 Invoke 来调用. 调用方法如下,其中 this 可以改为被调用的方法所属的类名,通过 BindingFlags ...
- Detecting Client Connection in WCF Long Running Service (Heartbeat Implementation) z
Download source - 45.3 KB Introduction Hello everyone! This is my first blog on WCF and I hope that ...
- 记一次JVM调优之旅(斗争full gc)
俗话说技多不压身,当年苦读<深入理解JVM>还专门整理了笔记,现在就用上了- 笔记 http://www.cnblogs.com/syjkfind/p/3901774.html [症状] ...
- 设计模式:解释器(Interpreter)模式
设计模式:解释器(Interpreter)模式 一.前言 这是我们23个设计模式中最后一个设计模式了,大家或许也没想到吧,竟然是编译原理上的编译器,这样说可能不对,因为编译器分为几个部分组成呢,比如词 ...
- jave web 监听器。
https://www.imooc.com/video/5664 Web监听器由Servlet规范提供的,可以监听客户端的请求以及服务端的操作,即监听ServletContext.HttpSessio ...
- JsonPath教程
1. 介绍 类似于XPath在xml文档中的定位,JsonPath表达式通常是用来路径检索或设置Json的.其表达式可以接受“dot–notation”和“bracket–notation”格式,例如 ...
- Hibernate初探之一对多映射 及 myeclipse自动生成hibernate文件方法
实现单向一对多: 1)在one方的实体中添加保存many方的集合 2)在one方的配置文件中添加<one-to-many>配置 实现单向多对一: 1)在many方的实体中添加one方的引用 ...