命名管道(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");
}