Linux初学,利用管道文件进行通信
目的:利用管道文件实现3个人之间的群聊,当有一个人退出时,剩余两个人之间还可以通信,继续有人退出时,程序自动关闭。
环境:Ubuntu
使用函数:open,read,write,select
文件准备:
1.c , 2.c ,3.c ,12.fifo,13.fifo,21.fifo,23.fifo,31.fifo,32.fifo
代码:
1.c:
//实现3个人之间的群聊,一个人如果先退出,剩下的两个还可以通信
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/select.h>
#include<sys/time.h>
#include<unistd.h>
#include<fcntl.h>
#define FIFO_12 "./12.fifo"
#define FIFO_21 "./21.fifo"
#define FIFO_13 "./13.fifo"
#define FIFO_31 "./31.fifo"
int main(int argc,char *argv[])
{
int fd_12,fd_21,fd_13,fd_31;
fd_12=open(FIFO_12,O_WRONLY);
fd_21=open(FIFO_21,O_RDONLY);
fd_13=open(FIFO_13,O_WRONLY);
fd_31=open(FIFO_31,O_RDONLY);
printf("连接成功,开始通信!\n");
char msg[1024];
int readn21,readn31,flag21=1,flag31=1;
int flag12=1,flag13=1;
int close2=0,close3=0;//检查通信对象2,3是否都关闭
while(1)
{
fd_set read_sets;
FD_ZERO(&read_sets);
FD_SET(0,&read_sets);
if(flag21==1) FD_SET(fd_21,&read_sets);//判断管道是否关闭,如果已经关闭则不加入监听集合
if(flag31==1) FD_SET(fd_31,&read_sets);
struct timeval tm;
tm.tv_sec=10;
tm.tv_usec=0;
printf(">>:\n");
select(1024,&read_sets,NULL,NULL,&tm);//只设置读操作集合,只需要读取其余两人发送的信息
if(FD_ISSET(0,&read_sets))//stdin ready,检查标准输入,1 准备发送消息到2 ,3
{
memset(msg,0,1024);
read(0,msg,1023);//将标准输入读到msg中
if(flag12==1)
{
write(fd_12,msg,strlen(msg));//写入1,2通信的管道
printf("\tsend a message to 2!\n");
}
if(flag13==1)
{
write(fd_13,msg,strlen(msg));//写入1,3通信的管道
printf("\tsend a message to 3!\n");
}
}
if(FD_ISSET(fd_21,&read_sets))//client 2 send a message,检查2是否有发送消息到1
{
if(readn21==0)
{
flag21=0;
flag12=0;
close2=1;
printf("2 is off!\n");
close(fd_21);
close(fd_12);
}
else
{
memset(msg,0,1024);
readn21=read(fd_21,msg,1023);
if(readn21!=0)
{
printf("\n\t2 send a message!\n");
printf("<<:\n\t%s\n",msg);
}
}
}
if(FD_ISSET(fd_31,&read_sets))//client3 send a message
{
if(readn31==0)
{
flag31=0;
flag13=0;
close3=1;
printf("3 is off!\n");
close(fd_31);
close(fd_13);
}
else
{
memset(msg,0,1024);
readn31=read(fd_31,msg,1023);
if(readn31!=0)
{
printf("\n\t3 send a message!\n");
printf("<<:\n\t%s\n",msg);
}
}
}
if(close2==1&&close3==1)//如果管道已经都关闭,则退出
break;
}
return 0;
}
2.c:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define FIFO_12 "./12.fifo"
#define FIFO_21 "./21.fifo"
#define FIFO_23 "./23.fifo"
#define FIFO_32 "./32.fifo"
int main(int argc,char *argv[])
{
int fd_12,fd_21,fd_23,fd_32;
fd_12=open(FIFO_12,O_RDONLY);
fd_21=open(FIFO_21,O_WRONLY);
fd_23=open(FIFO_23,O_WRONLY);
fd_32=open(FIFO_32,O_RDONLY);
printf("连接成功,开始通信!\n");
char msg[1024];
int readn12,readn32,flag12=1,flag32=1;
int flag21=1,flag23=1;
int close1=0,close3=0;
while(1)
{
//初始化
fd_set read_sets;
FD_ZERO(&read_sets);
//设置
FD_SET(0,&read_sets);
if(flag12==1)FD_SET(fd_12,&read_sets);
if(flag32==1)FD_SET(fd_32,&read_sets);
//时间
struct timeval tm;
tm.tv_sec=10;
tm.tv_usec=0;
printf(">>:\n");
select(1024,&read_sets,NULL,NULL,&tm);
if(FD_ISSET(0,&read_sets))
{
memset(msg,0,1024);
read(0,msg,1023);
if(flag21==1)
{
write(fd_21,msg,strlen(msg));
printf("\n\tsend a message to 1!\n");
}
if(flag23==1)
{
write(fd_23,msg,strlen(msg));
printf("\n\tsend a message to 3!\n");
}
}
if(FD_ISSET(fd_12,&read_sets))
{
if(readn12==0)
{
flag12=0;
flag21=0;
close1=1;
printf("1 is off!\n");
close(fd_12);
close(fd_21);
}
else
{
memset(msg,0,1024);
readn12=read(fd_12,msg,1023);
if(readn12!=0)
{
printf("\n\t1 send a message!\n");
printf("<<:\n\t%s\n",msg);
}
}
}
if(FD_ISSET(fd_32,&read_sets))
{
if(readn32==0)
{
flag32=0;
flag23=0;
close3=1;
printf("3 is off!\n");
close(fd_32);
close(fd_23);
}
else
{
memset(msg,0,1024);
readn32=read(fd_32,msg,1023);
if(readn32!=0)
{
printf("\n\t3 send a message!\n ");
printf("<<:\n\t%s\n",msg);
}
}
}
if(close1==1&&close3==1)
break;
}
return 0;
}
3.c:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define FIFO_13 "./13.fifo"
#define FIFO_31 "./31.fifo"
#define FIFO_23 "./23.fifo"
#define FIFO_32 "./32.fifo"
int main(int argc,char *argv[])
{
int fd_13,fd_31,fd_23,fd_32;
fd_13=open(FIFO_13,O_RDONLY);
fd_31=open(FIFO_31,O_WRONLY);
fd_23=open(FIFO_23,O_RDONLY);
fd_32=open(FIFO_32,O_WRONLY);
printf("连接成功,开始通信!\n");
char msg[1024];
int readn13,readn23,flag13=1,flag23=1;
int flag31=1,flag32=1;
int close1=0,close2=0;
while(1)
{
fd_set read_sets;
FD_ZERO(&read_sets);
FD_SET(0,&read_sets);
if(flag13==1) FD_SET(fd_13,&read_sets);
if(flag23==1) FD_SET(fd_23,&read_sets);
struct timeval tm;
tm.tv_sec=10;
tm.tv_usec=0;
printf(">>:\n");
select(1024,&read_sets,NULL,NULL,&tm);
if(FD_ISSET(0,&read_sets))
{
memset(msg,0,1024);
read(0,msg,1023);
if(flag31==1)
{
write(fd_31,msg,strlen(msg));
printf("\n\tsend a message to 1!\n");
}
if(flag32==1)
{
write(fd_32,msg,strlen(msg));
printf("\n\tsend a message to 2!\n");
}
}
if(FD_ISSET(fd_13,&read_sets))
{
if(readn13==0)
{
flag13=0;
flag31=0;
close1=1;
printf("1 is off!\n");
close(fd_13);
close(fd_31);
}
else
{
memset(msg,0,1024);
readn13=read(fd_13,msg,1023);
if(readn13!=0)
{
printf("\n\t1 send a message!\n");
printf("<<:\n\t%s\n",msg);
}
}
}
if(FD_ISSET(fd_23,&read_sets))
{
if(readn23==0)
{
flag23=0;
flag32=0;
close2=1;
printf("2 is off!\n");
close(fd_23);
close(fd_32);
}
else
{
memset(msg,0,1024);
readn23=read(fd_23,msg,1023);
if(readn23!=0)
{
printf("\n\t2 send a message!\n");
printf("<<:\n\t%s\n",msg);
}
}
}
if(close1==1&&close2==1)
break;
}
return 0;
}
生成可执行文件:gcc -g -o 1 1.c gcc -g -o 2 2.c gcc -g -o 3 3.c
结果演示:
1的通信记录:
2的通信记录:
3的通信记录:
总结:3个人之间的群聊,使用了6个管道文件,这只是管道文件的简单运用哈,使用了select函数。