进程间通信(5) 命名管道
- 可以在本機上實現兩個進程間的通信 支持跨網絡進程間的通信。
- 在創建管道時,可以指定具有訪問權限的用戶,而其他用戶則不能訪問這個管道。
- 將命名管道作為一種網絡編程方案時,它實際上建立了一個客戶機/服務器通信體系,并在其中可靠地傳輸數據。
- 采用“命名管道文件系統(Named Pipc File System,NPFS)”接口,因此,客戶機和服務器可利用標準的Win32文件系統函數(例如ReadFile和WriteFile)來進行數據的收發。
- 命名管道服務器和客戶機的區別在于:服務器是惟一一個有權創建命名管道的進程,也只有它才能接受管道客戶機的連接請求。而客戶機只能同一個現成的命名管道服務器建立連接。
1 步驟
a. 服務端用CreateNamedPipe創建一個命名管道并使用ConnectNamedPipe等待客戶端的連接。
b. 客戶端使用WaitNamedPipe連接成功后,用CreateFile打開管道并使用WriteFile向管道中寫入一段數據(即向服務端發送消息)。
c. 服務端使用ReadFile從管道中讀取數據后(即收到消息)再向管道中寫入確認信息表明已經收到客戶端傳輸的數據(即通知客戶端已收到)。
d. 客戶端收到確認信息后結束,調用CloseHandle關閉管道(該管道是CreateFile打開的)。
e.服務端使用DisconnectNamedPipe和CloseHandle關閉管道。
2. CreateNamedPipe 創建命名管道的第一個實例,并建立它的基本屬性
HANDLEWINAPI CreateNamedPipe( LPCTSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, // 指定管道能夠創建的實例的最大數目。該參數的取值范圍從1到PIPE_UNLIMITED_INSTANCES。DWORD nOutBufferSize, //輸出緩沖區所保留的字節數DWORD nInBufferSize, //輸入緩沖區所保留的字節數DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes );lpName
- 一個指向空終止的字符串,該字符串的格式必須是:“l.lpipelpipename”。
- 其中該字符串開始是兩個連續的反斜桿,其后的圓點表示是本地機器,如果想要與遠程的服務器建立連接,那么在這個圓點位置處應指定這個遠程服務器的名稱。
- 接下來是“pipe”這個固定的字符串,也就是說這個字符串的內容不能修改,但其大小寫是無所謂的。
- 最后是所創建的命名管道的名稱。
dwOpenMode
指定管道的訪問方式、重疊方式、寫直通方式,還有管道句柄的安全訪問方式。
重疊操作:對管道的讀寫函數將立即返回。
dwPipeMode
指定管道句柄的類型、讀取和等待方式。
- 當把命名管道指定為消息模式時,系統發送消息時有–個定界符 當我們以消息讀的模式去讀取時,通過該定界符就可以讀取到一條完整的消息
- 如果采用字節讀方式讀取,這時將忽略該定界符而直接讀取數據。 對消息模式的命名管道來說,可以采用消息讀,也可以采用字節讀的方式讀取數據。
- 對字節模式的命名管道來說,數據是一種字節流格式,沒有定界符,因此如果采用消息讀的模式讀取時,就不知道應該讀取多少字節的數據才合適。
nMaxInstances
對同一個命名管道的實例來說,在某一時刻,它只能和一個客戶端進行通信。
3. BOOL waitNamedPipe (LPCTSTR lpNamedPipeName,DWORD nTimeout );
nTimeout 超時時間間隔
4代碼
server
hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\MyPipe"),PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,0, 1, 1024, 1024, 0, NULL);if (INVALID_HANDLE_VALUE == hPipe){MessageBoxA(g_hWnd, "創建命名管道失敗!", "f", MB_OK); hPipe = NULL;return;}HANDLE hEvent;hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);if (!hEvent){MessageBoxA(g_hWnd, "創建事件對象失敗!", "f", MB_OK);CloseHandle(hPipe);hPipe = NULL;return;}OVERLAPPED ovlap;ZeroMemory(&ovlap, sizeof(OVERLAPPED));ovlap.hEvent = hEvent;if (!ConnectNamedPipe(hPipe, &ovlap)){if (ERROR_IO_PENDING != GetLastError()){MessageBoxA(g_hWnd, "等待客戶端連接失敗!", "f", MB_OK);CloseHandle(hPipe);CloseHandle(hEvent);hPipe = NULL;return;}}if (WAIT_FAILED == WaitForSingleObject(hEvent, INFINITE)){MessageBoxA(g_hWnd, "等待對象失敗!", "f", MB_OK);CloseHandle(hPipe);CloseHandle(hEvent);hPipe = NULL;return;}CloseHandle(hEvent);client:
if (!WaitNamedPipe(TEXT("\\\\.\\pipe\\MyPipe"), NMPWAIT_WAIT_FOREVER)){MessageBoxA(g_hWnd, "當前沒有可利用的命名管道實例!", "f", MB_OK); return;}hPipe = CreateFile(TEXT("\\\\.\\pipe\\MyPipe"), GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (INVALID_HANDLE_VALUE == hPipe){MessageBoxA(g_hWnd, "打開命名管道失敗!", "f", MB_OK); hPipe = NULL;return;}【引用】
總結
以上是生活随笔為你收集整理的进程间通信(5) 命名管道的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 区块链BaaS云服务(11)招商银行AB
- 下一篇: 区块链BaaS云服务(12)易居(中国)