Windows 之命名管道(一)

什麼是命名管道?

命名管道是一種簡單的進程間通信機制。這裏就不貼官方的說法了,說一下我自己的理解吧。命名管道就像一個頂級的大佬,和很多菜鳥,這個大佬告訴菜鳥們自己的家在哪裏,如果你們有事可以負責來找我,我會幫你們處理,但是不會主動去找你們詢問你們有什麼事情,然後大佬就在家裏等着了,如果菜鳥有事情,就找一條路去找大佬,解決完了就關閉這條路,當大佬想退休不幹的時候,就把自己家的地址給刪除了。

如何創建命名管道?

HANDLE WINAPI CreateNamedPipe(

  LPCTSTR lpName, // pipe name

  DWORD dwOpenMode, // read/write access (只讀,只寫,雙向)

  DWORD dwPipeMode, //

  DWORD nMaxInstances, // number of instances(默認爲255)

  DWORD nOutBufferSize, // output buffer size(0 表示使用默認大小)

  DWORD nInBufferSize, // input buffer size(0 表示使用默認大小)

  DWORD nDefaultTimeOut, //client time-out

  LPSECURITY_ATTRIBUTES lpSecurityAttributes

);

函數返回值:

函數執行成功返回命名管道的句柄,否則返回INVALID_HANDLE_VALUE

創建之後記得檢查句柄的返回值,如果句柄創建失敗,可以使用GetLastError() 函數返回錯誤值,查找失敗的原因。

 

如何使用命名管道?

命名管道的最大特點就是建立了一個基於服務器/客戶機的程序設計體系。在這個體系結構中,數據既可以單向流動,也可以雙向流動。但是服務器是唯一一個有權利創建命名管道的進程,也只有它有權利接受來自客戶端的鏈接請求。

  服務器的實現過程

  CreateNamedPipe();//創建命名管道實例句柄

  ConnectNamedPipe();//監聽來自客戶機的鏈接請求

  ReadFile(),WriteFile();//讀寫數據

  DisconnectNmaePipe();//關閉命名通道連接

  CloseHandle();//關閉命名管道實例句柄

  客戶端實現過程

  WaitNamedPipe();// 等候一個命名管道實例可供自己使用

  CreateFile();// 建立與命名管道的連接

  WriteFile(); ReadFile();//讀寫數據

  CloseHandle();// 關閉命名管道會話

具體的使用流程:

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

2. 客戶端使用WaitNamedPipe連接成功後,用CreateFile打開管道並使用WriteFile向管道中寫入一段數據(即向服務端發送消息)。

3. 服務端使用ReadFile從管道中讀取數據後(即收到消息)再向管道中寫入確認信息表明已經收到客戶端傳輸的數據(即通知客戶端已收到)。

4. 客戶端收到確認信息後結束,調用CloseHandle關閉管道(該管道是CreateFile打開的)。

5.服務端使用DisconnectNamedPipeCloseHandle關閉管道

 

涉及到的其它函數

ConnectNamedPipe

函數原型:

BOOL WINAPI ConnectNamedPipe(

   HANDLE hNamedPipe, // 命名管道句柄

   LPOVERLAPPED lpOverlapped //一般置爲NULL

);

 

WaitNamedPipe

函數原型:

BOOL WINAPI WaitNamedPipe(

   LPCTSTR lpNamedPipeName, //命名管道句柄

   DWORD nTimeOut //一個實例的超時時間,可以設置爲無限大

);

 

CreateFile

函數原型:

BOOL WINAPI CreatePipe(

   PHANDLE hReadPipe, //讀取端句柄

   PHANDLE hWritePipe, //寫入端句柄

   LPSECURITY_ATTRIBUTES lpPipeAttributes, //安全屬性

  DWORD nSize //緩衝區大小,0表示使用默認大小

);

 

WriteFile

函數原型:

BOOL WriteFile(

   HANDLE hFile, //句柄

   LPCVOID lpBuffer, //指向緩衝區的指針

  DWORD nNumberOfBytesToWrite,

   LPDWORD lpNumberOfBytesWritten,

   LPOVERLAPPED lpOverlapped //指定同步操作還是異步操作

);

 

ReadFile

函數原型:

BOO L ReadFile(

   HANDLE hFile, //句柄

   LPVOID lpBuffer, //指向緩衝區的指針

   DWORD nNumberOfBytesToRead,

   LPDWORD lpNumberOfBytesRead,

   LPOVERLAPPED lpOverlapped //指定同步操作還是異步操作

);

 

CloseHandle

函數原型:

BOOL CloseHandle(HANDLEhObject);

讀寫都關閉後才能調用該函數

 

DisconnectNamedPipe

函數原型:

HANDLE WINAPI DisconnectNamedPipe(HANDLE hNamedPipe);

 

CloseHandle

函數原型:

BOOL CloseHandle(HANDLE hObject);

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