命名管道使得没有关系的进程之间也可以进行通信,命名管道提供一个与之关联的路径名,
创建命名管道的方式:
因此,一个进程不需要与命名管道的创建具有相同的祖先,就可以通过该命名管道与之进行进程间的通信(只要可以访问该路劲名)。
实际上,命名管道就是利用建立于文件系统的特殊文件,以FIFO的文件形式存在于文件系统中,永久保存相关信息。
因此,不同的进程可以打开命名管道进行读写,从而实现通信。
对于命名管道的操作与文件操作非常相似,对文件操作中使用的函数read(),write(),close()等函数都可以是用来对管道进行操作。
下面以一个服务器和客户端的例子来进行简单地演示一下:
代码:
AllHead.h:
#pragma once
#include<errno.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<iostream>
#include<stdio.h>
#include<sys/wait.h>
using namespace std;
#define MAX_MSG_LEN 256
const char *write_fifo = "write_fifo";
const char *read_fifo = "read_fifo";
#include"AllHead.h"
extern int errno;//引入错误列表方便查找错误。
int main()
{
if(access("write_fifo",F_OK) == -1)//如果已经创建了就直接用就好了
{
int res = mkfifo("write_fifo",0666);//服务器创建管道并限定权限
if(res == -1)
{
cout<<"make write fifo error"<<endl;
perror("mkfifo");
exit(1);
}
}
int stat_val;
int pidser;
char sendbuf[MAX_MSG_LEN];
char recvbuf[MAX_MSG_LEN];
int write_fd= open(write_fifo,O_WRONLY);//绿色示意图
if(write_fd == -1)
{
cout<<"open write fifo eror"<<endl;
exit(1);
}
int read_fd = open(read_fifo,O_RDONLY);//红色示意图
if(read_fd == -1)
{
cout<<"open read fifo error"<<endl;
perror("open read_fifo");
exit(1);
}
pidser = fork();//为了能够多条发送开了条子进程负责
switch(pidser)
{
case 0://
while(1)
{
cout<<"mySer:> ";
gets(sendbuf);
if(strcmp(sendbuf,"quit") == 0)//正常结束掉已建好的管道
{
close(write_fd);
unlink("write_fifo");
exit(0);
}
else
write(write_fd,sendbuf,strlen(sendbuf)+1);
}
break;
case -1:
cout<<"error"<<endl;
exit(0);
default:
// wait(&stat_val);
while(1)
{
read(read_fd,recvbuf,MAX_MSG_LEN);
if(recvbuf == NULL)
{
wait(&stat_val);
exit(0);
}
else
{
cout<<"myCli:> "<<recvbuf<<endl;
}
}
wait(&stat_val);
break;
}
return 0;
}
mycli.cpp:
#include"AllHead.h"
extern int errno;
int main()
{
if(access("read_fifo",F_OK) == -1)
{
int res = mkfifo(read_fifo,0666);//客户端 创建一个读管道
if(res == -1)
{
cout<<"Create read_fifo error"<<endl;
perror("mkfifo");
exit(1);
}
}
int stat_val;
int pidcli;
char sendbuf[MAX_MSG_LEN];
char recvbuf[MAX_MSG_LEN];
int read_fd = open(write_fifo,O_RDONLY);//红色示意图。
if(read_fd == -1)
{
cout<<"open write fifo error"<<endl;
perror("open write_fifo");
exit(1);
}
int write_fd = open(read_fifo,O_WRONLY);//绿色示意图。
if(write_fd == -1)
{
cout<<"open read fifo error"<<endl;
unlink("read_fifo");
exit(1);
}
int n;
pidcli = fork();//为了实现多条发送,开了条子进程进行专门发送
switch(pidcli)
{
case 0://子进程
while(1)
{
cout<<"myCli:>";
gets(sendbuf);
if(strcmp(sendbuf,"quit") == 0)
{
close(write_fd);
unlink("write_fifo");
exit(0);
}
else
write(write_fd,sendbuf,strlen(sendbuf)+1);
}
break;
case -1:
cout<<"Create error"<<endl;
exit(0);
default://父进程接受完客户端的消息后就等子进程结束掉
// wait(&stat_val);
while(1)
{
read(read_fd,recvbuf,MAX_MSG_LEN);
if(recvbuf == NULL)
{
wait(&stat_val);
exit(0);
}
else
{
cout<<"myser:>"<<recvbuf<<endl;
}
}
wait(&stat_val);
break;
}
return 0;
}
引入下简单的makefile文件: