1、运行效果
2、单管道头文件
enum PipeType
{
UnKnowPipe,
NonePipe,
SinglePipe,
DoublePipe
};
typedef void(*DoxSyntony)();
typedef void *(*DoxSyntonyEx)();
typedef void(*DoxSyntonyParam)(void *);
typedef void *(*DoxSyntonyParamEx)(void *);
class PipeServer
{
public:
/* @接口 默认构造函数
* @邮箱 575814050@qq.com
*/
PipeServer();
/* @接口 默认析构函数
* @邮箱 575814050@qq.com
*/
~PipeServer();
/* @接口
* @返回 bool 成功返回值为true,否则返回值为false
* @邮箱 575814050@qq.com
*/
virtual bool beginPipe();
/* @接口 创建管道
* @返回 bool 成功返回值为true,否则返回值为false
* @邮箱 575814050@qq.com
*/
virtual bool createPipe();
/* @接口 创建子进程
* @返回 bool 成功返回值为true,否则返回值为false
* @邮箱 575814050@qq.com
*/
virtual bool createChild();
/* @接口 读取管道中的数据
* @返回 bool 成功返回值为true,否则返回值为false
* @邮箱 575814050@qq.com
*/
virtual QString readPipeData();
/* @接口 初始化管道
* @参数 管道类型
* @返回 bool 成功返回值为true,否则返回值为false
* @邮箱 575814050@qq.com
*/
virtual bool initPipe(PipeType);
/* @接口 往管道中写入数据
* @返回 bool 成功返回值为true,否则返回值为false
* @邮箱 575814050@qq.com
*/
virtual bool writePipeData(const QString &);
/* @接口
* @返回 bool 成功返回值为true,否则返回值为false
* @邮箱 575814050@qq.com
*/
virtual bool pickChild(const QString &child = "");
/* @接口 设置写数据以及读数据的回调
* @返回 bool 成功返回值为true,否则返回值为false
* @邮箱 575814050@qq.com
*/
virtual bool setOutputType(PPipeSyntony syntony = NULL);
private:
/* @接口 读取管道数据
* @返回 bool 成功返回值为true,否则返回值为false
* @邮箱 575814050@qq.com
*/
static DWORD readPipe(LPVOID);
/* @接口 写入管道数据
* @返回 bool 成功返回值为true,否则返回值为false
* @邮箱 575814050@qq.com
*/
static DWORD writePipe(LPVOID);
public:
QString _child;
PipeType _type;
HANDLE *_handle;
PPipeSyntony _syntony;
};
3、单管道源文件
const int BUFFESIZE = 4096;
PipeServer::PipeServer()
: _handle(NULL)
, _syntony(NULL)
, _type(UnKnowPipe)
{
}
PipeServer::~PipeServer()
{
if(_handle)
delete _handle;
_handle = NULL;
}
bool PipeServer::beginPipe()
{
if(!createPipe()) return false;
if(!createChild()) return false;
HANDLE handle[2];
handle[0] = CreateThread(NULL, 0, readPipe, this, 0, 0);
handle[1] = CreateThread(NULL, 0, writePipe, this, 0, 0);
WaitForMultipleObjects(2, handle, TRUE, INFINITE);
return true;
return true;
}
bool PipeServer::createPipe()
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
switch(_type)
{
case SinglePipe: _handle = new HANDLE[2];
return CreatePipe(&_handle[0], &_handle[1], &sa, 0);
break;
case DoublePipe: _handle = new HANDLE[4];
if(!CreatePipe(&_handle[0], &_handle[1], &sa, 0)) return false;
return CreatePipe(&_handle[2], &_handle[3], &sa, 0);
}
return true;
}
bool PipeServer::createChild()
{
STARTUPINFOA si; PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si)); ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si); GetStartupInfoA(&si); si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; DWORD ret;
si.hStdError = _handle[1]; si.hStdOutput = _handle[1]; si.hStdInput = _handle[2];
return CreateProcessA(NULL, _child.toLocal8Bit().data(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
}
QString PipeServer::readPipeData()
{
char buffer[BUFFESIZE] = { 0 }; BOOL ret = FALSE; DWORD somedate = 0;
while(!ret)
{
DWORD somedate = 0; memset(buffer, 0, sizeof(buffer));
ret = PeekNamedPipe(_handle[0], buffer, BUFFESIZE, &somedate, 0, 0);
}
ReadFile(_handle[0], buffer, BUFFESIZE, &somedate, 0);
return QS(buffer);
}
bool PipeServer::initPipe(PipeType type)
{
if(type == _type) return false;
return _type = type;
}
DWORD PipeServer::readPipe(LPVOID param)
{
PipeServer *pipe = (PipeServer *)param;
char buffer[BUFFESIZE] = { 0 }; DWORD ret = 0;
while(true)
{
DWORD somedate = 0; memset(buffer, 0, sizeof(buffer));
BOOL RET = PeekNamedPipe(pipe->_handle[0], buffer, BUFFESIZE, &somedate, 0, 0);
if(RET && somedate > 0)
{
int val = ReadFile(pipe->_handle[0], buffer, BUFFESIZE, &ret, 0);
pipe->_syntony->_write(buffer);
}
}
return 1;
}
DWORD PipeServer::writePipe(LPVOID param)
{
PipeServer *pipe = (PipeServer *)param;
char buffer[BUFFESIZE] = { 0 }; DWORD ret = 0;
while(true)
{
void *ptr = pipe->_syntony->_read();
QString cmd = *((QString *)ptr); cmd.append("\r\n");
cmd.replace("_", " ");
int val = WriteFile(pipe->_handle[3], cmd.toLocal8Bit().data(), cmd.length(), &ret, 0);
Sleep(100);
}
return 1;
}
bool PipeServer::pickChild(const QString &child)
{
_child = child.length() == 0 ? QS("cmd.exe") : child;
return true;
}
bool PipeServer::writePipeData(const QString &write)
{
QString cmd(write); cmd.replace("_", " "); DWORD ret = 0;
if(cmd.lastIndexOf("\r\n") == -1) cmd.append("\r\n");
int val = WriteFile(_handle[3], cmd.toLocal8Bit().data(), cmd.length(), &ret, 0);
Sleep(100); return val;
}
bool PipeServer::setOutputType(PPipeSyntony syntony)
{
if(syntony == _syntony) return false;
return _syntony = syntony;
}
4、主函数调用
void *sendInfo()
{
dox::Object<dox::IDoxPointer> pointer(NIL);
char buff[1024] = { 0 }; std::cin >> buff;return buff;
}
void recvInfo(void *info)
{
char *_recv = (char *)info->getPtr();
std::cout << _recv << std::endl;
}
void main()
{
PipeServer pipe(NIL);
pipe.initPipe(DoublePipe);
PipeSyntony _syntony;
_syntony._read = (DoxSyntonyEx)sendInfo;
_syntony._write = (DoxSyntonyParam)recvInfo;
pipe.pickChild(); pipe.setOutputType(&_syntony);
pipe.beginPipe();
}
示例程序下载地址:https://download.csdn.net/download/yangfahe1/10781733
示例程序运行方式:https://blog.csdn.net/yangfahe1/article/details/84028318