命名管道(NamedPipe)
简介:
命名管道(NamedPipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是:命名管道可以在不相关的进程之间
和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程
通信。命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机上两进程之间通信更困难,不过如果要同时和多个进程通信它
就力不从心了.
作用:
在计算机编程里,命名管道是一种从一个进程到另一个进程用内核对象来进行信息传输。和一般的管道不同,命名管道可以被不同进程以不同的方
式方法调用(可以跨权限、跨语言、跨平台)。只要程序知道命名管道的名字,发送到命名管道里的信息可以被一切拥有指定授权的程序读取,但
对不具有制定授权的。命名管道是一种FIFO(先进先出,First-In First-Out)对象。
看个简单的demo 在本机上一个客户端和一个服务端通信
Server code:
// pipelineServer.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include <Windows.h>
/*
*
* 进程间通信 命名管道 server
*
*
*
*/
int main()
{
char buff[256];
DWORD len = 0;
HANDLE h_Pipe = CreateNamedPipe(
TEXT("\\\\.\\Pipe\\mypipe"), //管道名字
PIPE_ACCESS_DUPLEX, //管道类型
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, //管道参数
PIPE_UNLIMITED_INSTANCES, //管道能创建的最大实例数量
0, //输出缓冲区的长度 0表示默认
0, //输入缓冲区的长度 0表示默认
NMPWAIT_WAIT_FOREVER, //超时时间
NULL);
if (h_Pipe == INVALID_HANDLE_VALUE)
{
std::cout << "Failed to CreateNamedPipe!"<<std::endl;
return -1;
}
std::cout << "CreateNamedPipe success!"<<std::endl;
std::cout << "waiting client connect..."<<std::endl;
if (ConnectNamedPipe(h_Pipe, NULL) == NULL) //阻塞客户端来连接
{
std::cout << "Failed to Connect!" << std::endl;
}
else
{
std::cout << "Connect success!" << std::endl;
}
while (true)
{
if (ReadFile(h_Pipe, buff, 256, &len, NULL) == FALSE) //接收客户端发送的内容
{
std::cout << "Failed to read data!" << std::endl;
break;
}
else
{
std::cout << "read data:" << buff << ",data size:" << len <<std::endl;
char d[256] = "i am server ,hello client";
DWORD len_ = 0;
WriteFile(h_Pipe, d, sizeof(d), &len_, 0); //向客户端发送内容
std::cout << "send data:" << d << ",data size:" << len_ << std::endl;
Sleep(1000);
}
}
CloseHandle(h_Pipe); //关闭管道释放资源
system("pause");
}
Client Code:
// pipelineClient.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include <Windows.h>
/*
*
* 进程间通信 命名管道 client
*
*
*
*/
int main()
{
DWORD len = 0;
bool bRet = WaitNamedPipe(TEXT("\\\\.\\Pipe\\mypipe"), NMPWAIT_WAIT_FOREVER);
if (!bRet)
{
std::cout << "Failed to connect pipeline!" << std::endl;
return -1;
}
HANDLE h_Pipe = CreateFile( //管道属于一种特殊的文件
TEXT("\\\\.\\Pipe\\mypipe"), //文件名字
GENERIC_READ | GENERIC_WRITE, //文件模式
0, //是否共享
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, //文件属性(只读,默认...)NORMAL 为默认属性
NULL);
if (h_Pipe == INVALID_HANDLE_VALUE)
{
std::cout << "Failed to CreateFile pipeline file!" << std::endl;
}
else
{
while (true)
{
char buff[256] = "i am client ,hello server!";
if (WriteFile(h_Pipe, buff, sizeof(buff), &len, 0) == FALSE) //向服务器发数据
{
std::cout << "write faile to server failed!" << std::endl;
break;
}
else
{
std::cout << "send data to server:" << buff << ",data size:" << len << std::endl;
char recvData[256] = "";
DWORD rlen = 0;
ReadFile(h_Pipe, recvData, sizeof(recvData), &rlen, 0); //接收服务器内容
std::cout << "receive data form server:" << recvData << ",data size:" << rlen << std::endl;
}
Sleep(1000);
}
}
CloseHandle(h_Pipe);
system("pause");
}