1.命名管道原理
2.代码实现命名管道
首先认识一个函数,他可以形成一个命名管道
头文件:
#include <sys/types.h>
#include <sys/stat.h>
函数体:
int mkfifo(const char *pathname, mode_t mode);
第一个参数是新建的命名管道放在哪个路径下的路径字符串,第二个参数为该文件的打开权限
同时shell提供指令 mkfifo +命名管道名也能形成管道,会新建在当前路径下
unlink函数实现删除管道
头文件:
#include <unistd.h>
函数体:
int unlink(const char *pathname);
参数为命名管道文件的所在路径
总规划
1.send.cc该进程进行发送数据
2.reception.cc该进程进行接收数据
3.namepipe.hpp该文件进行配置环境
4.makefile对两个.cc文件进行编译
1.makefile编写
.PHONY:all
all:send reception
send:send.cc
g++ -o send send.cc -std=c++11
reception:reception.cc
g++ -o reception reception.cc -std=c++11
.PHONY:clean
clean:
rm -rf send reception
2.namepipe.hpp先完成命名管道的创建以及删除操作
我们使用cpp,可以用类来封装管道的创建以及删除
namepipe.hpp
#include<iostream>
#include <sys/types.h> //mkfifo的头文件open头文件
#include<string>
#include <sys/stat.h> //mkfifo的头文件open头文件
#include <unistd.h> //unlink头文件/close头文件
using namespace std;
const string com_path="./myfifo";
#define Defaultfd -1
#define Creater 1
#define User 2
class Namepipe
{
public:
Namepipe(const string &path,int who)
:_fifo_path(path)
,_id(who)
,_fd(Defaultfd)
{
if(_id==Creater)
{
int ret=mkfifo(_fifo_path.c_str(),0666);
if(ret!=0)
{
perror("mkfifo");
}
cout<<"creater create named pipe"<<endl;
}
}
~Namepipe()
{
if(_id==Creater)
{
int ret=unlink(_fifo_path.c_str());
if(ret!=0)
{
perror("unlink");
}
cout<<"creater free namepipe"<<endl;
}
if(_fd!= Defaultfd)close(_fd);
}
private:
const string _fifo_path;
int _id;
int _fd;
};
send.cc
#include"namepipe.hpp"
int main()
{
Namepipe fifo(com_path,User);
}
reception.cc
#include"namepipe.hpp"
int main()
{Namepipe fifo(com_path,Creater);
}
3. send .cc文件,reception.cc打开命名管道文件,分配文件操作符
reception.cc
#include"namepipe.hpp"
int main()
{Namepipe fifo(com_path,Creater);
if(fifo.openforread())
{
cout<<"reception open name pipe done"<<endl;
}
}
send .cc
#include"namepipe.hpp"
int main()
{
Namepipe fifo(com_path,User);
if(fifo.openforwrite())
{
cout<<"send open namepipe done"<<endl;
}
}
namepipe.hpp
为了更清楚的展示,没有写构造和析构
#define Read O_RDONLY
#define Write O_WRONLY
#define Basesize 1024
class Namepipe
{
private:
bool opennamepipe(int mode)
{
_fd=open(_fifo_path.c_str(),mode);
if(_fd<0)
return false;
return true;
}
public:
bool openforread()
{return opennamepipe(Read);
}
bool openforwrite()
{
return opennamepipe(Write);
}
private:
const string _fifo_path;
int _id;
int _fd;
};
该步骤完成后,如上图所示
4.send进程写入命名管道数据
send.cc
#include"namepipe.hpp"
int main()
{
Namepipe fifo(com_path,User);
if(fifo.openforwrite())
{
cout<<"send open namepipe done"<<endl;
while(true)
{
cout<<"please Enter>";
string message;
getline(cin,message);
fifo.writenamepipe(message);
}
}
return 0;
}
namepipe.hpp(只保留本步骤的)
#define Basesize 1024
class Namepipe
{
public:
int writenamepipe(const string &in)
{
return write(_fd,in.c_str(),in.size());
}
private:
const string _fifo_path;
int _id;
int _fd;
};
5.reception进程读内核缓冲区的数据
namepipe.hpp
class Namepipe
{
public:
int readnamepipe(string *out)
{
char buffer[Basesize];
int n=read(_fd,buffer,sizeof(buffer));
if(n>0)
{buffer[n]=0;
*out=buffer;
}
return n;
}
private:
const string _fifo_path;
int _id;
int _fd;
};
reception.cc
#include"namepipe.hpp"
int main()
{Namepipe fifo(com_path,Creater);
if(fifo.openforread())
{
cout<<"reception open name pipe done"<<endl;
while(true)
{
string message;
int n=fifo.readnamepipe(&message);
if(n>0)
{
cout<<"send say>"<<message<<endl;
}
else if(n==0)
{
cout<<"send quit,reception too!"<<endl;
break;
}
else
{
cout<<"fifo.readnamepipe error"<<endl;
break;
}
}
}
}
–
整体代码
reception.cc
#include"namepipe.hpp"
int main()
{Namepipe fifo(com_path,Creater);
if(fifo.openforread())
{
cout<<"reception open name pipe done"<<endl;
while(true)
{
string message;
int n=fifo.readnamepipe(&message);
if(n>0)
{
cout<<"send say>"<<message<<endl;
}
else if(n==0)
{
cout<<"send quit,reception too!"<<endl;
break;
}
else
{
cout<<"fifo.readnamepipe error"<<endl;
break;
}
}
}
}
send.cc
#include"namepipe.hpp"
int main()
{
Namepipe fifo(com_path,User);
if(fifo.openforwrite())
{
cout<<"send open namepipe done"<<endl;
while(true)
{
cout<<"please Enter>";
string message;
getline(cin,message);
fifo.writenamepipe(message);
}
}
return 0;
}
namepipe.hpp
#include<iostream>
#include <sys/types.h> //mkfifo的头文件open头文件
#include<string>
#include <sys/stat.h> //mkfifo的头文件open头文件
#include <unistd.h> //unlink头文件/close头文件
#include <fcntl.h> //open头文件
using namespace std;
const string com_path="./myfifo";
#define Defaultfd -1
#define Creater 1
#define User 2
#define Read O_RDONLY
#define Write O_WRONLY
#define Basesize 1024
class Namepipe
{
private:
bool opennamepipe(int mode)
{
_fd=open(_fifo_path.c_str(),mode);
if(_fd<0)
return false;
return true;
}
public:
Namepipe(const string &path,int who)
:_fifo_path(path)
,_id(who)
,_fd(Defaultfd)
{
if(_id==Creater)
{
int ret=mkfifo(_fifo_path.c_str(),0666);
if(ret!=0)
{
perror("mkfifo");
}
cout<<"creater create named pipe"<<endl;
}
}
~Namepipe()
{
if(_id==Creater)
{
int ret=unlink(_fifo_path.c_str());
if(ret!=0)
{
perror("unlink");
}
cout<<"creater free namepipe"<<endl;
}
if(_fd!= Defaultfd)close(_fd);
}
bool openforread()
{
return opennamepipe(Read);
}
bool openforwrite()
{
return opennamepipe(Write);
}
int writenamepipe(const string &in)
{
return write(_fd,in.c_str(),in.size());
}
int readnamepipe(string *out)
{
char buffer[Basesize];
int n=read(_fd,buffer,sizeof(buffer));
if(n>0)
{buffer[n]=0;
*out=buffer;
}
return n;
}
private:
const string _fifo_path;
int _id;
int _fd;
};
命名管道