什麼是命名管道?
命名管道是一種簡單的進程間通信機制。這裏就不貼官方的說法了,說一下我自己的理解吧。命名管道就像一個頂級的大佬,和很多菜鳥,這個大佬告訴菜鳥們自己的家在哪裏,如果你們有事可以負責來找我,我會幫你們處理,但是不會主動去找你們詢問你們有什麼事情,然後大佬就在家裏等着了,如果菜鳥有事情,就找一條路去找大佬,解決完了就關閉這條路,當大佬想退休不幹的時候,就把自己家的地址給刪除了。
如何創建命名管道?
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.服務端使用DisconnectNamedPipe和CloseHandle關閉管道
涉及到的其它函數
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);