管道是最初的unix ipc形式,它的侷限性在於沒有名字,只能在有親緣關係的程序間使用。後來,fifo出現了,fifo也稱為有名管道。管道和fifo都使用read和write函式訪問。
#include int pipe(int fd[2]);
管道由pipe函式建立,返回兩個描述符:fd[0]用來讀,fd[1]用來寫。
單個程序建立管道後,程序、核心和管道之間的關係如下:
通常情況下,單個程序建立管道後,會呼叫fork建立乙個子程序,然後父子程序之間使用管道通訊。如下圖所示:
如果父程序要向子程序傳遞訊息,則父程序關閉管道的讀一端,子程序關閉管道的寫一端。如下圖所示:
然而,只建立乙個管道,父子程序間只有從父程序到子程序的單向資料流。為了父子程序間傳遞雙向的資料流,父程序在fork之前需要建立兩個管道。在fork後,父程序關閉管道1的讀出端和管道2的寫入端,子程序關閉管道1的寫入端和管道2的讀出端。如下圖所示:
下面給出乙個用管道實現客戶-伺服器之間通訊的例子。
在這個例子中,客戶從標準輸入讀入檔案路徑,將路徑名傳送給伺服器。伺服器根據客戶傳送的路徑名開啟檔案,然後將檔案內容(或錯誤資訊)傳送給客戶。客戶則讀取檔案內容(或錯誤資訊)到標準輸出。
如上圖4-6所示,為實現這個例子,我們使用兩個管道,客戶作為父程序,伺服器作為子程序。第乙個管道用於客戶向伺服器傳送路徑名,第二個管道用於伺服器向客戶傳送檔案內容(或錯誤資訊)。**如下:
#include "unpipc.h"
void client(int, int);
void server(int, int);
int main(int argc, char **argv)
/*父程序*/
close(pipe1[0]); /*關閉管道1的讀出端*/
close(pipe2[1]); /*關閉管道2的寫入端*/
client(pipe2[0], pipe1[1]);
/*等待子程序結束*/
waitpid(childpid, null, 0);
exit(0);
}void client(int readfd, int writefd)
void server(int readfd, int writefd)
buff[n] = '\0';
if ((fd = open(buff, o_rdonly)) < 0) else
}
熟悉shell的朋友會知道,shell中符號『|』用於在兩個命令(程式)間建立管道,將乙個命令的標準輸出寫入到另乙個命令的標準輸入。這樣可以將多個命令關聯起來,提供更強大的功能。標準庫裡面就提供了popen函式實現這樣功能,使用它可以讀取乙個程式的標準輸出或寫入內容到它的標準輸入。
#include file *popen(const char *command, const char *type);
int pclose(file *stream);
引數command是乙個命令列,這個命令由shell執行。返回值是乙個檔案流。如果引數type為「r」,則讀這個檔案流返回命令列的標準輸出。如果引數type是「w」,寫這個檔案流即寫入內容到命令列的標準輸入。
下面給出乙個popen的例子。
#include "unpipc.h"
int main(int argc, char **argv)
pclose(fp);
exit(0);
}
在這個例子中,我們從標準輸入讀入檔案路徑,傳遞給cat程式,然後呼叫popen獲取cat程式的標準輸出(檔案的內容或出錯資訊),輸出到標準輸出。 《UNIX網路程式設計 卷1》 筆記 UNIX域協議
unix域協議並不是乙個實際的協議族,而是在單個主機上客戶程序和伺服器程序之間通訊的一種方法。unix域使用的套接字結構如下 struct sockaddr un int main int argc,char argv 執行結果如下 可以看到繫結的路徑名 tmp 123 現在是乙個套接字檔案。uni...
《UNIX網路程式設計 卷2》 筆記 位元組流與訊息
目前我們給出的管道和fifo的例子通訊雙方使用的都是位元組流i o模型,程式不對它作任何解釋。舉個例子,如果乙個程序從fifo收到100位元組資料,它不知道這100位元組資料是乙個程序傳送的還是多個程序傳送的。如何區分位元組流是哪個程序傳送的?有種常用的技巧就是將資料封裝在一條訊息 可以理解為帶邊界...
《UNIX網路程式設計 卷1》 筆記 高階I O函式
本節我們關注稱為 高階i o 的各個函式和技術。首先是在i o操作上設定超時。在涉及套接字的i o操作上設定超時的方法有以下3種 1.呼叫alarm函式,在定時時間超時產生sigalrm訊號,打斷i o操作。首先我們給出要使用的signal1函式的實現,這個函式不是系統呼叫signal的包裹函式,而...