C++的創建命名管道(CreateNamedPipe)

一、命名管道(Named Pipes)

管道(Pipe)實際是用於進程間通信的一段共享內存,創建管道的進程稱爲管道服務器,連接到一個管道的進程爲管道客戶機。一個進程在向管道寫入數據後,另一進程就可以從管道的另一端將其讀取出來。

匿名管道(Anonymous Pipes)是在父進程和子進程間單向傳輸數據的一種未命名的管道,只能在本地計算機中使用,而不可用於網絡間的通信。

命名管道,顧名思義,這個管道肯定是有名字的。通過管道的名字來確保多個進程訪問同一個管道。事實上,命名管道不僅可在同一臺計算機的不同進程之間傳輸數據,甚至能在跨越一個網絡的不同計算機的不同進程之間,支持可靠的、單向或雙向的數據通信。

重要函數

CreateNamedPipe

函數功能:創建命名管道

HANDLEWINAPICreateNamedPipe(

  LPCTSTRlpName,

  DWORDdwOpenMode,

  DWORDdwPipeMode,

  DWORDnMaxInstances,

  DWORDnOutBufferSize,

  DWORDnInBufferSize,

  DWORDnDefaultTimeOut,

  LPSECURITY_ATTRIBUTESlpSecurityAttributes

);

ConnectNamedPipe

函數功能:等待客戶端連接命名管道

函數原型:

BOOLWINAPIConnectNamedPipe(

  HANDLEhNamedPipe,

  LPOVERLAPPEDlpOverlapped

);

WaitNamedPipe

函數功能:客戶端連接命名管道

函數原型:

BOOLWINAPIWaitNamedPipe(

  LPCTSTRlpNamedPipeName,

  DWORDnTimeOut

);

二、實例

下面給出使用命名管道的實例,該實例分爲命名管道的服務端和客戶端。服務端和客戶端的主要步驟如下所示:

1. 服務端用CreateNamedPipe創建一個命名管道並使用ConnectNamedPipe等待客戶端的連接

2. 客戶端使用WaitNamedPipe連接成功後,用CreateFile打開管道

3、服務端使用WriteFile向管道中寫入一段數據(即向客戶端發送消息)

4、客戶端使用ReadFile從管道中讀取數據,顯示,調用CloseHandle關閉管道(該管道是CreateFile打開的)。

5、服務端使用DisconnectNamedPipe和CloseHandle關閉管道。

服務端代碼

#include <iostream>
#include <windows.h>
#include <ctime>
using namespace std;

int main()
{
	printf("創建命名管道並等待連接\n");

	HANDLE hPipe = CreateNamedPipe(L"\\\\.\\Pipe\\mypipe", PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT
		, PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_WAIT_FOREVER, 0);


	//waiting to be connected
	if (ConnectNamedPipe(hPipe, NULL) != NULL)
	{
		printf("連接成功,開始發送數據\n");

		DWORD    dwWrite;
		const char *pStr = "data from server";
		if (!WriteFile(hPipe, pStr, strlen(pStr), &dwWrite, NULL))
		{
			cout << "write failed..." << endl << endl;
			return 0;
		}
		cout << "sent data: " << endl << pStr << endl << endl;
	}

	DisconnectNamedPipe(hPipe);
	CloseHandle(hPipe);//關閉管道
	printf("關閉管道\n");
	system("pause");
}

客戶端代碼

// ClientPip.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//

#include <iostream>
#include <windows.h>
#include <ctime>
#include <conio.h>
using namespace std;
#define BUFSIZE 5


int main()
{

	printf("命名管道:客戶端上線\n");
	printf("按任意鍵以開始連接命名管道\n");
	_getch();
	printf("開始等待命名管道\n");

	if (WaitNamedPipe(L"\\\\.\\Pipe\\mypipe", NMPWAIT_WAIT_FOREVER) == FALSE)
		return 0;

	printf("打開命名管道\n");
	HANDLE hPipe = CreateFile(L"\\\\.\\Pipe\\mypipe", GENERIC_READ | GENERIC_WRITE, 0,
		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	if ((long)hPipe == -1)
		return 0;


	//接收服務端發回的數據
	BOOL fSuccess = false;
	DWORD len = 0;
	char buffer[BUFSIZE];
	string recvData = "";
	do
	{
		fSuccess = ReadFile(hPipe, buffer, BUFSIZE * sizeof(char), &len, NULL);
		char buffer2[BUFSIZE + 1] = { 0 };
		memcpy(buffer2, buffer, len);
		recvData.append(buffer2);
		if (!fSuccess || len < BUFSIZE)
			break;
	} while (true);

	cout << "recv data:" << endl << recvData.c_str() << endl << endl;

	FlushFileBuffers(hPipe);
	DisconnectNamedPipe(hPipe);
	CloseHandle(hPipe);

	system("pause");
	return 0;
}

先打開服務器,再打開客戶端

 

參考:

https://blog.csdn.net/MoreWindows/article/details/8260087?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

https://www.cnblogs.com/nanfei/p/10858307.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章