技術:IPC,RPC,Windows General
主題:Named Pipe,Inter-process Communication
概要:
命名管道是一種進程間單工或雙工的通信機制。它可以在管道服務器和一個或多個管道客戶端間進行。客戶端可以位於本機或互聯網上的遠程計算機。
PIPE_ACCESS_INBOUND(呼入):
Client (GENERIC_WRITE) ---> Server (GENERIC_READ)
PIPE_ACCESS_OUTBOUND(外傳):
Client (GENERIC_READ) <--- Server (GENERIC_WRITE)
PIPE_ACCESS_DUPLEX(雙工):
Client (GENERIC_READ or GENERIC_WRITE, or both) <-->
Server (GENERIC_READ and GENERIC_WRITE)
GENERIC_READ(普通讀)
GENERIC_WRITE(普通寫)
下面的代碼示例演示了如何調用CreateNamedPipe來創建一個名稱為"\\.\pipe\SamplePipe", 的管道。支持全雙工連接。這樣客戶端和服務端都可以從管道中讀寫數據。自定義安全選項使得認證的用戶才具有對管道的讀寫權限。當有客戶端連接管道時,服務端嘗試調用ReadFile從管道中讀出客戶端的消息,並通過調用WriteFile寫入響應消息。
如何演示:
1.在VS2008中編譯CppNamedPipeClient 和CppNamedPipeServer 兩個工程,如果成功你會獲得兩個可執行文件CppNamedPipeClient.exe 和 CppNamedPipeServer.exe.
2.運行CppNamedPipeServer.exe。如果管道創建成功,程序會以命令行形式輸出以下信息:
Server:
The named pipe (\\.\pipe\SamplePipe) is created.
Waiting for the client's connection...
3.運行CppNamedPipeClient.exe。如果客戶端成功連接到命名管道會輸出下列信息:
Client:
The named pipe (\\.\pipe\SamplePipe) is connected.
同時服務器端會輸出下面的消息來指示有一個客戶端連接到管道
Server:
Client is connected.
4.接下來客戶端會嘗試寫入消息到命名管道,程序輸出:
Client:
Send 56 bytes to server: "Default request from client"
當服務端從客戶端讀取消息後打印出:
Server:
Receive 56 bytes from client: "Default request from client"
接下來,服務端寫入一個回應消息到管道。
Server:
Send 58 bytes to client: "Default response from server"
然後客戶端收到回應消息輸出:
Client:
Receive 58 bytes from server: "Default response from server"
最後斷開連接,關閉管道。
主要代碼邏輯:
1.調用CreateNamedPipe創建一個命名管道,指明管道的名稱,方向,傳輸模式,安全屬性等
// Create the named pipe.
hNamedPipe = CreateNamedPipe(
FULL_PIPE_NAME, // Pipe name.
PIPE_ACCESS_DUPLEX, // The pipe is duplex; both server and
// client processes can read from and
// write to the pipe
PIPE_TYPE_MESSAGE | // Message type pipe
PIPE_READMODE_MESSAGE | // Message-read mode
PIPE_WAIT, // Blocking mode is enabled
PIPE_UNLIMITED_INSTANCES, // Max. instances
BUFFER_SIZE, // Output buffer size in bytes
BUFFER_SIZE, // Input buffer size in bytes
NMPWAIT_USE_DEFAULT_WAIT, // Time-out interval
pSa // Security attributes
);
在這個事例中管道支持全雙工通信。安全屬性允許認證用戶具有讀寫管道權限,所有管理員組成員具有對管道的全部權限
//
// FUNCTION: CreatePipeSecurity(PSECURITY_ATTRIBUTES *)
//
// PURPOSE: The CreatePipeSecurity function creates and initializes a new
// SECURITY_ATTRIBUTES structure to allow Authenticated Users read and
// write access to a pipe, and to allow the Administrators group full
// access to the pipe.
//
// PARAMETERS:
// * ppSa - output a pointer to a SECURITY_ATTRIBUTES structure that allows
// Authenticated Users read and write access to a pipe, and allows the
// Administrators group full access to the pipe. The structure must be
// freed by calling FreePipeSecurity.
//
// RETURN VALUE: Returns TRUE if the function succeeds..
//
// EXAMPLE CALL:
//
// PSECURITY_ATTRIBUTES pSa = NULL;
// if (CreatePipeSecurity(&pSa))
// {
// // Use the security attributes
// // ...
//
// FreePipeSecurity(pSa);
// }
//
BOOL CreatePipeSecurity(PSECURITY_ATTRIBUTES *ppSa)