上篇博客我们说过在这篇博客我们将改进我们上篇博客写的,命名管道实现简易通信,下面是改进之后的代码,这里我不详细写出来,希望大家可以凭借上节课的知识以及代码内容,真正的自己理解并且复现一遍~~
Makefile:
cpp
.PHONEY : all
all : server client
server : server.cc
g++ server.cc -o server
client : client.cc
g++ client.cc -o client
.PHONEY : clean
clean :
rm -f client server
server.cc:
cpp
#include "common.hpp"
int main()
{
NamedFifo fifo(PATH, FIFO_FILE);
FifoOper server(PATH, FIFO_FILE);
server.OpenForRead();
server.Read();
server.Close();
return 0;
}
client.cc:
cpp
#include "common.hpp"
int main()
{
FifoOper client(PATH, FIFO_FILE);
client.OpenForWrite();
client.Write();
client.Close();
return 0;
}
common.hpp:
cpp
#pragma once
#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PATH "."
#define FIFO_FILE "fifo"
class NamedFifo
{
public:
NamedFifo(std::string path, std::string name)
: _path(path)
, _name(name)
{
umask(0);
_fifoname = _path + "/" + _name;
int n = mkfifo(_fifoname.c_str(), 0666);
if (n == -1)
{
std::cout << "mkfifo fail" << std::endl;
}
else
{
std::cout << "mkfifo success" << std::endl;
}
}
~NamedFifo()
{
int n = unlink(_fifoname.c_str());
if (n == -1)
{
std::cout << "~fifo fail" << std::endl;
}
else
{
std::cout << "~fifo success" << std::endl;
}
}
private:
std::string _path;
std::string _name;
std::string _fifoname;
};
class FifoOper
{
public:
FifoOper(std::string path, std::string name)
: _path(path)
, _name(name)
, _fd(-1)
{
_fifoname = _path + "/" + _name;
}
~FifoOper()
{
std::cout << "~FifoOper" << std::endl;
}
void OpenForRead()
{
_fd = open(_fifoname.c_str(), O_RDONLY);
if (_fd < 0)
{
std::cout << "OpenForRead fail" << std::endl;
return;
}
std::cout << "OpenForRead success" << std::endl;
}
void OpenForWrite()
{
_fd = open(_fifoname.c_str(), O_WRONLY);
if (_fd < 0)
{
std::cout << "OpenForWrite fail" << std::endl;
return;
}
std::cout << "OpenForWrite success" << std::endl;
}
void Read()
{
char buffer[1024];
while (true)
{
int number = read(_fd, buffer, sizeof(buffer) - 1);
if (number > 0)
{
buffer[number] = '\0';
std::cout << "client say : " << buffer << std::endl;
}
else if (number == 0)
{
std::cout << "client quit! server quit, too!" << std::endl;
break;
}
else
{
std::cout << "Read error" << std::endl;
break;
}
}
}
void Write()
{
std::string message;
while (true)
{
std::cout << "please enter# ";
std::getline(std::cin, message);
write(_fd, message.c_str(), message.size());
}
}
void Close()
{
if (_fd > 0)
close(_fd);
}
private:
std::string _path;
std::string _name;
std::string _fifoname;
int _fd;
};
这就算有关管道通信的知识啦(命名管道与匿名管道),但是我们的通信之旅还没有完,大家敬请期待后续内容啦~~