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 ...
随机推荐
- “云中论道”之——使用开源技术和Azure公有云服务快速搭建云端IoT解决方案(上)
“云中论道”技术课堂第一课开讲啦!微软各路技术咖们齐聚一堂,为大家带来干货不断!作为“云中论道“课堂的开课之作,我们首先邀请到了微软Azure专家级的架构师:槐长清,他为我们带来了关于“使用开源技术和 ...
- java中double类型显示两个小数,比如12.00
Double类型的数据如何保留两位小数? 各位大虾,现有Double类型的数据,如何转换为保留两位小数的数,返回值的类型仍然是Double类型的,而不是字符串类型. 比如 0,返回“0.00” ...
- SQL 查询:查询学生平均成绩
编程萌新,因为遇到这么个SQL 查询的问题:在一张表A里有如下字段:学生姓名.学科名.学科成绩.写一条SQL 语句查出各科平均成绩并按学生姓名分组,按如下格式显示:学生姓名|语文|数学|英语.一开始遇 ...
- shell 脚本中后台执行命令 &
最近遇到一个问题, 执行脚本,脚本调用 一个命令,命令(deamon)是一个守护进程,为了调试,取消了守护进程模式.导致命令后边的其他命令(echo "456")都无法执行. de ...
- 如何在 MSBuild Target(Exec)中报告编译错误和编译警告
编译错误和编译警告 MSBuild 的 Exec 自带有错误和警告的标准格式,按照此格式输出,将被识别为编译错误和编译警告. 而格式只是简简单单的 error: 开头或者 warning: 开头.冒号 ...
- ZT 设计模式六大原则(4):接口隔离原则
设计模式六大原则(4):接口隔离原则 分类: 设计模式 2012-02-27 08:32 17948人阅读 评论(21) 收藏 举报 设计模式classinterfacecstring框架 定义:客户 ...
- kali配置ip,更新源,更新签名
以下是我在简单玩kali时候碰到的一些问题,然后找到的解决办法,能成功解决我当时碰到的问题,如果你有疑问或者碰到不能解决的问题可以在下面评论 ############################# ...
- Override和Overload的含义去区别
java中的继承,方法覆盖(重写)override与方法的重载overload的区别 方法的重写(Overriding)和重载(Overloading)是Java多态性的不同表现. 重写(Ove ...
- redis持久化那些事(kēng)儿
这是一篇包含了介绍性质和吐槽性质的日志.主要介绍一下我学习redis持久化时候被坑的经历.redis的使用介绍现在没有打算写,因为比较多,以我如此懒的性格...好吧,还是有点这方面想法的,不过一篇博客 ...
- MySQL数据库----------小知识点
**********************补2016年5月23日的博客************************* MySQL数据库 常用数据类型: int 整数 ...