進程間通訊 —— 命名管道

管道包括三種:windows

1):普通管道PIPE,一般有不少限制,一是半雙工,只能單向傳輸,二是隻能在父子進程間使用安全

2):流管道:這種能雙向傳輸,可是也是隻能父子進程間使用。服務器

3):命名管道,去除了以上的第二種限制,能夠在許多不相關的進程間進行通信。也是半雙工的通訊方式。網絡

  一般咱們把管道分爲匿名管道和命名管道。但對於匿名管道的話,只能在本機上進程之間通訊,並且只能實現本地的父子進程之間的通訊,侷限性太大了。命名管道,就和匿名管道有些不一樣了,在功能上也就顯得強大許多,至少其能夠實現跨網絡之間的進程的通訊,同時其客戶端既能夠接收數據也能夠發送數據,服務器端也是能夠接收數據,又能夠發送數據。異步

 

匿名管道的概述函數

  對於匿名管道而言,命名管道使用了windows安全機制,於是命名管道的服務器端能夠控制哪些客戶有權與其創建鏈接。哪些客戶端是不可以與這個命名管道創建鏈接的。命名管道的通訊是以鏈接的方式進行的,服務器建立一個命名管道對象,而後在此對象上等待鏈接請求,一旦客戶鏈接過來,則二者均可以經過命名管道讀或者寫數據。測試

    命名管道提供了兩種通訊模式:字節模式和消息模式。在字節模式下,數據以一個連續的字節流的形式在客戶機和服務器之間流動。而在消息模式下,客戶機和服務器則經過一系列不連續的數據單位,進行數據的收發,每次在管道上發出一個消息後,它必須做爲一個完整的消息讀入。spa

 

命名管道的使用步驟指針

  服務器端:code

1):服務器進程調用CreateNamedPipe函數來建立一個有名稱的命名管道在建立命名管道的時候必須指定一個本地的命名管道名稱。windows容許同一個本地的命名管道名稱右多個命名管道實例。因此,服務器進程在調用CreateNamedPipe函數時必須指定最大容許的實例數(0-255).若是CreateNamedPipe函數成功返回後,服務器進程獲得一個指向一個命名管道實例的句柄。

2):服務器進程就能夠調用ConnectNamedPipe來等待客戶的鏈接請求,這個ConnectNamedPipe既支持同步形式,又支持異步形式,若服務器進程以同步形式調用 ConnectNamedPipe函數,若是沒有獲得客戶端的鏈接請求,則會一直等到客戶端的鏈接請求。當該函數返回時,客戶端和服務器之間的命名管道鏈接已經創建起來了。

3):這個時候服務器端就能夠向客戶端讀(ReadFile)/寫(WriteFile)數據了。

4):在已經創建鏈接的命名管道實例中,服務器進程就會獲得一個指向該管道實例的句柄,這個句柄稱之爲服務器端句柄,同時服務端進程能夠調用DisconnectNamedPipe函數,將一個管道實例與當前創建鏈接的客戶端進程斷開,從而能夠從新鏈接到新的客戶端進程。固然,服務器也能夠調用CloseHandle來關閉一個已經創建鏈接的命名管道實例。

 

客戶端:

1):客戶端進程調用CreateFile函數鏈接到一個正在等待鏈接的命名管道上。在這裏客戶端須要指定將要鏈接的命名管道上。當CreateFile成功返回以後,客戶端就獲得了一個指向已經創建鏈接的命名管道實例的句柄。在這裏客戶端也能夠先調用WaitNamedPipe函數來測試指定名稱的管道實例是否可用。在已經創建的命名管道實例中,客戶端進程就會獲得一個指向該管道實例的句柄。這個句柄稱之爲客戶端句柄。

2):這個時候客戶端就能夠向服務器讀(ReadFile)/寫(WriteFile)數據了.

3):客戶端能夠調用CloseHandle來關閉一個已經創建鏈接的命名管道實例。

 

 

CreateNamedPipe:

 1 //建立命名管道的函數的使用
 2 CreateNamedPipe("\\\\.\\Pipe\\Test",PIPE_ACCESS_DUPLEX,PIPE_NOWAIT,10,1024,1024,100,NULL)  3 1、爲建立的管道命名  4 2、指定管道的訪問方式、重疊方式、寫直通方式以及管道句柄的安全訪問方式(PIPE_ACCESS_DUPLEX這裏指雙向模式)  5 3、指定管道句柄的類型、讀取和等待方式(PIPE_NOWAIT指容許非阻塞方式)  6 4、指定管道可以建立的實例的最大數目  7 5、指定爲輸出緩衝區所保留的字節數  8 6、指定爲輸入緩衝區所保留的字節數  9 7、指定默認超時時間,單位ms,同一管道的不一樣實例指定值須要相同 10 8、指向SECURITY_ATTRIBUTES結構的指針,該結構指定了命名管道的安全描述符

   該函數用來建立一個命名管道的實例,並返回這個命名管道的句柄。若是須要建立一個命名管道的多個實例,就須要屢次調用CreateNamedPipe函數,參數 lpName 爲一個字符串,其格式必須爲 \\.\pipe\pipeName,其中圓點 」.」 表示的是本地機器,若是想要與遠程的服務器創建鏈接,那麼這個圓點位置處應指定這個遠程服務器的名稱,而其中的 「pipe」 這個是個固定的字符串,也就是說不能進行改變的,最後的 「pipename」 則表明的是我將要建立的命名管道的名稱了,參數 dwOpenMode 用來指定管道的訪問方式,重疊方式,寫直通方式,還有管道句柄的安全訪問方式。

ConnectNamedPipe:

1 //服務器等待客戶端的鏈接請求的到來(並不是鏈接服務器端的命名管道!)
2 ConnectNamedPipe(hPipe, NULL) 3 1、指向一個命名管道實例的服務器的句柄,該句柄由CreateNamedPipe函數返回 4 2、指向OVERLAPPED結構體的指針,默認爲NULL,代表使用默認的同步IO方式
接收客戶端發送數據ReadFile & 向客戶端發送數據WriteFile:
1 //文件的寫入
2 WriteFile(hPipe, strMessage, sizeof(strMessage), &wLen, 0) 3 
4 1、指定要寫入數據的文件的句柄 5 2、指向包含將要將要寫入文件的數據的緩衝區的指針 6 3、指明要向文件中寫入的字節數 7 4、用來接收實際寫入到文件中的字節數 8 5、指向OVERLAPPED結構體的指針,默認爲NULL,代表使用默認的同步IO方式

 

//文件的讀取

1 ReadFile(hPipe, buf, 256, &rLen, NULL) 2 1、指定要讀取數據的文件的句柄 3 2、指向包含將要將要接收的文件中讀取數據的緩衝區的指針 4 3、指明要向文件中讀取的字節數 5 4、用來接收實際讀取到的字節數 6 5、指向OVERLAPPED結構體的指針,默認爲NULL,代表使用默認的同步IO方式


CloseHandle:

CloseHandle(hPipe);    //關閉管道句柄 

 



客戶端單獨用到的兩個函數

WaitNamedPipe:

1 WaitNamedPipe(TEXT("\\\\.\\Pipe\\pipeTest"), NMPWAIT_WAIT_FOREVER) 2 1、指定命名管道的名稱 3 2、指定超時間隔,NMPWAIT_WAIT_FOREVER表示一直等待,直到出現了一個可用的命名管道的實例

 


CreateFile:

CreateFile("\\\\.\\Pipe\\Test",GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 1、指定用於建立或打開的對象的名稱 2、指定對象的訪問方式,GENERIC_WRITE表示指定對象具備寫訪問 3、指定共享方式,若是此參數爲0,表示對象不能被共享 4、指向SECURITY_ATTRIBUTES結構的指針,該結構指定了命名管道的安全描述符,若是沒有特殊的需求,默認值爲NULL 5、指定如何建立文件(OPEN_EXISTING表示打開文件,若是文件不存在,則函數調用失敗) 6、設置文件屬性和標誌(FILE_ATTRIBUTE_NORMAL表示該文件沒有其餘屬性設置) 7、指定具備GENERIC_READ訪問方式的模板文件的句柄
相關文章
相關標籤/搜索