命名管道

“命名管道”又名“命名管線”(Named Pipes),是一種簡單的進程間通信(IPC)機制,Microsoft Windows大都提供了對它的支持(但不包括Windows CE)。命名管道可在同一臺計算機的不同進程之間或在跨越一個網絡的不同計算機的不同進程之間,支持可靠的、單向或雙向的數(shù)據(jù)通信。推薦用命名管道作為進程通信方案的一項重要的原因是它們充分利用了Windows內建的安全特性(ACL等)。
用命名管道來設計跨計算機應用程序實際非常簡單,并不需要事先深入掌握底層網絡傳送協(xié)議(如TCP、UDP、IP、IPX)的知識。這是由于命名管道利用了微軟網絡提供者(MSNP)重定向器通過同一個網絡在各進程間建立通信,這樣一來,應用程序便不必關心網絡協(xié)議的細節(jié)。

命名管道基本信息

中文名 命名管道 外文名 Named Pipes
支持平臺 Windows,Linux,Unix等

序言

我們會對命名管道已知的所有問題及限制進行總結.

實例1

在一個程序中實現(xiàn)命名管道的創(chuàng)建與使用

實例2

此示例代碼意在體現(xiàn)出命名管道與普通管道的區(qū)別,命名管道是以一個普通文件的形式出現(xiàn)的,包括三個文件,創(chuàng)建命名管道、寫管道、讀管道

1. 創(chuàng)建命名管道

#include<sys/types.h>

#include<sys/stat.h>

#include<unistd.h>

#include<fcntl.h>

int main(void){

char buf[80];

int fd;

unlink("zieckey_fifo");

mkfifo("zieckey_fifo",0777);}寫命名管道代碼

#include<sys/types.h>

#include<sys/stat.h>

#include<unistd.h>

#include<fcntl.h>

int main(void){

int fd;

char s[]="Hello!\n";

fd=open("zieckey_fifo",O_WRONLY);

while(1){

write(fd,s,sizeof(s));

sleep(1);}

return0;

}

讀命名管道代碼

#include<sys/types.h>

#include<sys/stat.h>

#include<unistd.h>

#include<fcntl.h>

int main(void){

int fd;

char buf[80];

fd = open("zieckey_fifo",O_RDONLY);

while(1){

read(fd,buf,sizeof(buf));

printf("%s\n",buf);

sleep(1); }

return0;

}

命名管道造價信息

市場價 信息價 詢價
材料名稱 規(guī)格/型號 市場價
(除稅)
工程建議價
(除稅)
行情 品牌 單位 稅率 供應商 報價日期
管道 公稱直徑DN(mm):50,規(guī)格型號:24 查看價格 查看價格

卓奧

m 13% 江蘇卓奧節(jié)能設備安裝工程有限公司浙江辦事處
管道式換氣扇 DPT20-54B 風量:770m3/H;功率:0.145KW;噪聲:35DB(A),風壓:200PA 查看價格 查看價格

雄吉通風

13% 重慶市雄吉通風設備股份有限公司
給水用鋼絲網增強聚乙烯復合管道1.6MPA Ф200 查看價格 查看價格

顧地

m 13% 重慶顧地塑膠電器有限公司
管道及附件 包含系統(tǒng)內所含的管道、彎頭、三通、法蘭等 查看價格 查看價格

13% 上海熊貓機械(集團)有限公司
鋼纖增強聚乙烯復合壓力管道(含聚氨酯保溫層及PE外護套) DN200×8.5 1.6MPa 查看價格 查看價格

粵星管道

m 13% 廣東建通管道制品有限公司
鋼纖增強聚乙烯復合壓力管道(含聚氨酯保溫層及PE外護套) DN350×13 1.6MPa 查看價格 查看價格

粵星管道

m 13% 廣東建通管道制品有限公司
給水用鋼絲網增強聚乙烯復合管道1.6MPA Ф160 查看價格 查看價格

顧地

m 13% 重慶顧地塑膠電器有限公司
鋼纖增強聚乙烯復合壓力管道(含聚氨酯保溫層及PE外護套) DN100×6.5 1.6MPa 查看價格 查看價格

粵星管道

m 13% 廣東建通管道制品有限公司
材料名稱 規(guī)格/型號 除稅
信息價
含稅
信息價
行情 品牌 單位 稅率 地區(qū)/時間
環(huán)衛(wèi)管道疏通機 功率1.5(kW) 查看價格 查看價格

臺班 韶關市2010年8月信息價
9A151 查看價格 查看價格

臺班 汕頭市2012年4季度信息價
功率120kW 查看價格 查看價格

臺班 汕頭市2012年4季度信息價
功率160kW 查看價格 查看價格

臺班 汕頭市2012年4季度信息價
9A151 查看價格 查看價格

臺班 汕頭市2012年3季度信息價
功率240kW 查看價格 查看價格

臺班 汕頭市2012年3季度信息價
功率120kW 查看價格 查看價格

臺班 汕頭市2012年3季度信息價
9A151 查看價格 查看價格

臺班 汕頭市2012年1季度信息價
材料名稱 規(guī)格/需求量 報價數(shù) 最新報價
(元)
供應商 報價地區(qū) 最新報價時間
變壓器命名 變壓器命名牌|1臺 1 查看價格 廣西  來賓市 2012-12-04
管道系統(tǒng) 包括進出水管道、藥劑輸送管道、污泥管道、自來水管道、壓縮空氣|1項 1 查看價格 廣東岑安機電有限公司 全國   2022-08-02
命名 命名牌 型號規(guī)格:方通龍骨+木紋鋁板 仿木紋色+深褐色 500x200xH2100|9個 3 查看價格 廣東雙子標識科技有限公司 廣東   2020-11-17
管道支架 管道支架|1000kg 1 查看價格 廣州珠江管業(yè)科技有限公司 廣東  廣州市 2019-07-05
管道支架 管道支架|100kg 1 查看價格 廣州珠江管業(yè)科技有限公司 廣東  廣州市 2019-07-05
管道清理疏通 含吸污車吸取、運輸,管道沖洗|12000m 1 查看價格 成都美妙一環(huán)保工程有限公司 四川   2022-07-12
CPVC管道 種類 CPVC 公稱外徑 20(mm) 壁厚 2.4(mm) 長度 4(m) 拉伸強度 10(MPa) 用途 化工管道 每件重量 0.5(kg)|5890m 1 查看價格 睿智昊通管道閥門(北京)有限公司 北京  北京市 2015-03-30
管道(組合管道) 側向+縱向抗震支架,SXZ-7,具體參數(shù)詳見圖紙|5套 3 查看價格 喜利得中國商貿有限公司 廣東  深圳市 2019-12-04

假定有一臺服務器保存著公司的秘密,我們要求只有公司的管理人員才能訪問或編輯這些秘密(高權限信息)。而在自己的工作網絡,公司內的每名員工都可看到網絡上的這臺計算機(低權限訪問)。然而,我們并不希望普通員工(低權限組)取得對機密材料的訪問權。公司要求我們開發(fā)一個數(shù)據(jù)管理系統(tǒng),此系統(tǒng)只允許一個指定的用戶組(高權限組)進行操作。

在這種情況下,命名管道等包含ACL的數(shù)據(jù)通信系統(tǒng)可發(fā)揮作用。因為我們可利用ACL,使只有擁有特別權限的用戶(高權限組)與指定服務器發(fā)送控制信息,以此對公司的秘密進行操作。在此要記住的一個重點是:將命名管道作為一種網絡編程方案使用時,它實際上建立一個簡單的客戶機/服務器數(shù)據(jù)通信體系(通常是TCP/IP,TCP協(xié)議具有良好的穩(wěn)定性與數(shù)據(jù)安全性)。

要學習開發(fā)一組命名管道應用(可能是一個進程的不同線程、同一個可執(zhí)行性文件的不同實例或完全不同的程序),首先要了解命名管道的命名規(guī)范(命名協(xié)議),然后了解基本的管道類型,接著實現(xiàn)一組簡單的服務器應用與一個客戶端應用。然后再以它為基礎,深入研究高級的服務器編程技術,了解更復雜的通信系統(tǒng)與簡單的通信協(xié)議。

在計算機編程里,命名管道是一種從一個進程到另一個進程用內核對象來進行信息傳輸。和一般的管道不同,命名管道可以被不同進程以不同的方式方法調用(可以跨權限、跨語言、跨平臺)。只要程序知道命名管道的名字,發(fā)送到命名管道里的信息可以被一切擁有指定授權的程序讀取,但對不具有制定授權的。命名管道是一種FIFO(先進先出,F(xiàn)irst-In First-Out)對象。

命名管道常見問題

命名管道(NamedPipe)是服務器進程和一個或多個客戶進程之間通信的單向或雙向管道。不同于匿名管道的是:命名管道可以在不相關的進程之間和不同計算機之間使用,服務器建立命名管道時給它指定一個名字,任何進程都可以通過該名字打開管道的另一端,根據(jù)給定的權限和服務器進程通信。命名管道提供了相對簡單的編程接口,使通過網絡傳輸數(shù)據(jù)并不比同一計算機上兩進程之間通信更困難,不過如果要同時和多個進程通信它就力不從心了。

命名管道實例1

在一個程序中實現(xiàn)命名管道的創(chuàng)建與使用。

#include
 
  
#include
  
    #include
   
     #include
    
      intmain( void) { charbuf[80]; intfd; unlink("zieckey_fifo");mkfifo("zieckey_fifo",0777); if( fork()>0) { chars[]="Hello! "; fd=open("zieckey_fifo",O_WRONLY); write(fd,s,sizeof(s)); //close(fd); } else { fd=open("zieckey_fifo",O_RDONLY); read(fd,buf,sizeof(buf));printf("Themessagefromthepipes:%s ",buf); //close(fd); } return0; } /*執(zhí)行結果為 Themessagefromthepipes:Hello! 并且可以在程序執(zhí)行目錄生成管道文件zieckey_fifo */
    
   
  
 

命名管道實例2

此示例代碼意在體現(xiàn)出命名管道與普通管道的區(qū)別,命名管道是以一個普通文件的形式出現(xiàn)的,包括三個文件操作:創(chuàng)建命名管道、寫管道、讀管道。

1. 創(chuàng)建命名管道

#include
 
  #include
  
   #include
   
    #include
    
     intmain(void){charbuf[80];intfd;unlink("zieckey_fifo");mkfifo("zieckey_fifo",0777);} 
    
   
  
 

寫命名管道代碼

#include
 
  #include
  
   #include
   
    #include
    
     intmain(void){intfd;chars[]="Hello! ";fd=open("zieckey_fifo",O_WRONLY); while (1){ write(fd,s,sizeof(s)); sleep(1); }return0;} 
    
   
  
 

讀命名管道代碼

#include
 
  #include
  
   #include
   
    #include
    
     intmain(void){intfd;charbuf[80];fd=open("zieckey_fifo",O_RDONLY);while(1){read(fd,buf,sizeof(buf));printf("%s ",buf);sleep(1);}return0;}
    
   
  
 

命名管道文獻

PDMS管道命名規(guī)則 PDMS管道命名規(guī)則

格式:pdf

大小:416KB

頁數(shù): 58頁

評分: 4.7

PLEASE NOTE: CADCentre has a policy of continuing product development: therefore, the information contained in this document may be subject to change without notice. CADCENTRE MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS DOCUMENT, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. While every effort has been made to verify the

立即下載
管道與管道附件知識 管道與管道附件知識

格式:pdf

大?。?span id="0n080cy" class="single-tag-height">416KB

頁數(shù): 48頁

評分: 4.8

??????????? ???? 1 ?????????????????????????????????? ?????? ???????????????? ???????? ?????????????????????? ???????????????????????????????? ????????????????????????????? ????????? ???????? ???????????????? ??????????????? 2 ?????? * ??????? ????????????????????????????????? ???????? ---???---??---??? ????? ????????? ??????? ????? ??????? ???????????????? ?????? * ?????? *?????? *????? 3 ???

立即下載

命名管道程序設計的實現(xiàn)

1.命名管道Server和Client間通信的實現(xiàn)流程

(1)建立連接:服務端通過函數(shù)CreateNamedPipe創(chuàng)建一個命名管道的實例并返回用于今后操作的句柄,或為已存在的管道創(chuàng)建新的實例。如果在已定義超時值變?yōu)榱阋郧埃幸粋€實例管道可以使用,則創(chuàng)建成功并返回管道句柄,并用以偵聽來自客戶端的連接請求,該功能通過ConnectNamedPipe函數(shù)實現(xiàn)。

另一方面,客戶端通過函數(shù)WaitNamedPipe使服務進程等待來自客戶的實例連接,如果在超時值變?yōu)榱阋郧?,有一個管道可以為連接使用,則WaitNamedPipe將返回True,并通過調用CreateFile或CallNamedPipe來呼叫對服務端的連接。此時服務端將接受客戶端的連接請求,成功建立連接,服務端ConnectNamedPipe返回True,客戶端CreateFile將返回一指向管道文件的句柄。

從時序上講,首先是客戶端通過WaitNamedPipe使服務端的CreateFile在限時時間內創(chuàng)建實例成功,然后雙方通過ConnectNamedPipe和CreateFile成功連接,并返回用以通信的文件句柄,此時雙方即可進行通信。

(2)通信實現(xiàn):建立連接之后,客戶端與服務器端即可通過ReadFile和WriteFile,利用得到的管道文件句柄,彼此間進行信息交換。

(3)連接終止:當客戶端與服務端的通信結束,或由于某種原因一方需要斷開時,客戶端應調用CloseFile,而服務端應接著調用DisconnectNamedPipe。當然服務端亦可通過單方面調用DisconnectNamedPipe終止連接。最后應調用函數(shù)CloseHandle來關閉該管道。

命名管道服務器端和客戶端代碼實現(xiàn)

客戶端

HANDLE CltHandle;

char pipenamestr[30];

sprintf(pipenamestr,″\\servername\pipe\pipename″)

if (WaitNamedPipe( pipenamestr, NMPWAIT—WAIT—FOREVER)==FALSE

// 管道名要遵循UNC,格式為\ \.\pipe\pipname,名字不分大小寫。

AfxMessageBox(″操作失敗,請確定服務端正確建立管道實例!″);

Else

CltHandle=CreateFile(pipenamestr, GENERIC—READ|GENERIC—WRITE, FILE—SHARE—READ| FILE—SHARE—WRITE,NULL, OPEN—EXISTING,

//為了與命名管道連接,此參數(shù)應一直為OPEN—EXISTING

FILE—ATTRIBUTE—ARCHIVE|FILE—FLAG—WRITE—THROUGH,

// FILE—FLAG—WRITE—THROUGH會使管道WriteFile調用處于阻塞狀態(tài),直到數(shù)據(jù)傳送成功。

NULL);

If (CltHandle== INVALID—HANDLE—VALUE)

AfxMessageBox(″管道連接失敗″);

Else

DoUsertTransactInfo();

//執(zhí)行用戶自定義信息交換函數(shù)——從管道讀、寫信息。

……

服務端

HANDLE SvrHandle;

char pipenamestr[30];

sprintf(pipenamestr,″\\.\pipe\pipename″)

SvrHandle=CreateNamedPipe(pipenamestr,

PIPE—ACCESS—DUPLEX|FILE—FLAG—WRITE—THROUGH,

//阻塞模式,這種模式僅對″字節(jié)傳輸管道″操作有效。

FILE—WAIT|PIPE—TYPE—BYTE,

//字節(jié)模式

PIPE—UNLIMITED—INSTANCES,

128,128,

NULL,NULL);

// SECURITY—ATTRIBUTES結構指針,描述一個新管道,確定子進程的繼承權,如果為NULL則該命名管道不能被繼承。

If (SvrHandle==INVALID—HANDLE—VALUE)

AfxMessageBox(″管道創(chuàng)建失敗,請確定客戶端提供連接可能!″);

Else

If (ConnectNamedPipe(SvrHandle,NULL)==FALSE)

AfxMessageBox(″建立連接失?。 ?;

Else

DoUsertTransactInfo();

//用戶自定義信息交換函數(shù)

……

使用靈活性

命名管道具有很好的使用靈活性,表現(xiàn)在:

1) 既可用于本地,又可用于網絡。

2) 可以通過它的名稱而被引用。

3) 支持多客戶機連接。

4) 支持雙向通信。

5) 支持異步重疊I/O操作。

不過,當前只有Windows NT支持服務端的命名管道技術。

命名管道是由服務器端的進程建立的,管道的命名必須遵循特定的命名方法,就是 "\\.\pipe\管道名",當作為客戶端的進程要使用時,使用"\\計算機名\\pipe\管道名" 來打開使用,具體步驟如下:

服務端通過函數(shù) CreateNamedPipe 創(chuàng)建一個命名管道的實例并返回用于今后操作的句柄,或為已存在的管道創(chuàng)建新的實例。 服務端偵聽來自客戶端的連接請求,該功能通過 ConnectNamedPipe 函數(shù)實現(xiàn)。 客戶端通過函數(shù) WaitNamedPipe 來等待管道的出現(xiàn),如果在超時值變?yōu)榱阋郧埃幸粋€管道可以使用,則 WaitNamedPipe 將返回 True,并通過調用 CreateFile 或 CallNamedPipe 來呼叫對服務端的連接。 此時服務端將接受客戶端的連接請求,成功建立連接,服務端 ConnectNamedPipe 返回 True 建立連接之后,客戶端與服務器端即可通過 ReadFile 和 WriteFile,利用得到的管道文件句柄,彼此間進行信息交換。 當客戶端與服務端的通信結束,客戶端調用 CloseFile,服務端接著調用 DisconnectNamedPipe。最后調用函數(shù)CloseHandle來關閉該管道。 由于命名管道使用時作為客戶端的程序必須知道管道的名稱,所以更多的用在同一"作者"編寫的服務器/工作站程序中,你不可能隨便找出一個程序來要求它和你寫的程序來通過命名管道通信。而匿名管道的使用則完全不同,它允許你和完全不相干的進程通信,條件是這個進程通過控制臺"console"來輸入輸出,典型的例子是老的 Dos 應用程序,它們在運行時 Windows 為它們開了個 Dos 窗口,它們的輸入輸出就是 console 方式的。還有一些標準的 Win32 程序也使用控制臺輸入輸出,如果在 Win32 編程中不想使用圖形界面,你照樣可以使用 AllocConsole 得到一個控制臺,然后通過 GetStdHandle 得到輸入或輸出句柄,再通過 WriteConsole 或 WriteFile 把結果輸出到控制臺(通常是一個象 Dos 窗口)的屏幕上。雖然這些程序看起來象 Dos 程序,但它們是不折不扣的 Win32 程序,如果你在純 Dos 下使用,就會顯示"The program must run under Windows!"。

一個控制臺有三個句柄:標準輸入、標準輸出和和標準錯誤句柄,標準輸入、標準輸出句柄是可以重新定向的,你可以用匿名管道來代替它,這樣一來,你可以在管道的另一端用別的進程來接收或輸入,而控制臺一方并沒有感到什么不同,就象 Dos 下的 > 或者 < 可以重新定向輸出或輸入一樣。通??刂婆_程序的輸入輸出如下:

(控制臺進程output) write ----> 標準輸出設備(一般是屏幕)

(控制臺進程input) read <---- 標準輸入設備(一般是鍵盤)

而用管道代替后:

(作為子進程的控制臺進程output) write ----> 管道1 ----> read (父進程)

(作為子進程的控制臺進程input) read <----> 管道2 <---- write (父進程)

使用匿名管道的步驟如下:

使用 CreatePipe 建立兩個管道,得到管道句柄,一個用來輸入,一個用來輸出 準備執(zhí)行控制臺子進程,首先使用 GetStartupInfo 得到 StartupInfo 使用第一個管道句柄代替 StartupInfo 中的 hStdInput,第二個代替 hStdOutput、hStdError,即標準輸入、輸出、錯誤句柄 使用 CreateProcess 執(zhí)行子進程,這樣建立的子進程輸入和輸出就被定向到管道中 父進程通過 ReadFile 讀第二個管道來獲得子進程的輸出,通過 WriteFile 寫第一個管道來將輸入寫到子進程 父進程可以通過 PeekNamedPipe 來查詢子進程有沒有輸出 子進程結束后,要通過 CloseHandle 來關閉兩個管道。 下面是具體的說明和定義:

1. 建立匿名管道使用 CreatePipe 原形如下:

BOOL CreatePipe(

PHANDLE hReadPipe, // address of variable for read handle

PHANDLE hWritePipe, // address of variable for write handle

LPSECURITY_ATTRIBUTES lpPipeAttributes, // pointer to security attributes

DWORD nSize // number of bytes reserved for pipe

);

當管道建立后,結構中指向的 hReadPipe 和 hWritePipe 可用來讀寫管道,當然由于匿名管道是單向的,你只能使用其中的一個句柄,參數(shù)中的 SECURITY_ATTRIBUTES 的結構必須填寫,定義如下:

typedef struct_SECURITY_ATTRIBUTES{

DWORD nLength: //定義以字節(jié)為單位的此結構的長度

LPVOID lpSecurityDescriptor; //指向控制這個對象共享的安全描述符,如果為NULL這個對象將被分配一個缺省的安全描述

BOOL bInheritHandle; //當一個新過程被創(chuàng)建時,定義其返回是否是繼承的.供系統(tǒng)API函數(shù)使用.

}SECURITY_ATTRIBUTES;

2. 填寫創(chuàng)建子進程用的 STARTUPINFO 結構,一般我們可以先用 GetStartupInfo 來填寫一個缺省的結構,然后改動我們用得到的地方,它們是:

hStdInput -- 用其中一個管道的 hWritePipe 代替 hStdOutput、hStdError -- 用另一個管道的 hReadPipe 代替 dwFlags -- 設置為 STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW 表示輸入輸出句柄及 wShowWindow 字段有效 wShowWindow -- 設置為 SW_HIDE,這樣子進程執(zhí)行時不顯示窗口。 填寫好以后,就可以用 CreateProcess 來執(zhí)行子進程了,具體有關執(zhí)行子進程的操作可以參考上一篇教程《進程控制》

3. 在程序中可以用 PeekNamedPipe 查詢子進程有沒有輸出,原形如下:

BOOL PeekNamedPipe(

HANDLE hNamedPipe, // handle to pipe to copy from

LPVOID lpBuffer, // pointer to data buffer

DWORD nBufferSize, // size, in bytes, of data buffer

LPDWORD lpBytesRead, // pointer to number of bytes read

LPDWORD lpTotalBytesAvail, // pointer to total number of bytes available

LPDWORD lpBytesLeftThisMessage // pointer to unread bytes in this message

);

我們可以將嘗試讀取 nBuffersize 大小的數(shù)據(jù),然后可以通過返回的 BytesRead 得到管道中有多少數(shù)據(jù),如果不等于零,則表示有數(shù)據(jù)可以讀取。

4. 用 ReadFile 和 WriteFile 來讀寫管道,它們的參數(shù)是完全一樣的,原形如下:

ReadFile or WriteFile(

HANDLE hFile, // handle of file to read 在這里使用管道句柄

LPVOID lpBuffer, // address of buffer that receives data 緩沖區(qū)地址

DWORD nNumberOfBytesToRead, // number of bytes to read 準備讀寫的字節(jié)數(shù)

LPDWORD lpNumberOfBytesRead, // address of number of bytes read,實際讀到的或寫入的字節(jié)數(shù)

LPOVERLAPPED lpOverlapped // address of structure for data 在這里用 NULL

);

5. 用 CloseHandle 關閉管道一和管道二的 hReadPipe和 hWritePipe 這四個句柄。

下面給出了一個例子程序,這個程序是上篇教程《進程控制》的例子的擴充,如果你對有的 api 感到陌生的話,請先閱讀上一篇教程。

命名管道相關推薦
  • 相關百科
  • 相關知識
  • 相關專欄