天天看點

UNIX Domain Socket IPC

UNIX Domain Socket是全雙工的,API接口語義豐富,相比其它IPC機制有明顯的優越性,目前已成為使用最廣泛的IPC機制,比如X Window伺服器和GUI程式之間就是通過UNIX Domain Socket通訊的。

使用UNIX Domain Socket的過程和網絡socket十分相似,也要先調用socket()建立一個socket檔案描述符,address family指定為AF_UNIX,type可以選擇SOCK_DGRAM或SOCK_STREAM,protocol參數仍然指定為0即可。

UNIX Domain Socket與網絡socket程式設計最明顯的不同在于位址格式不同,用結構體sockaddr_un表示,網絡程式設計的socket位址是IP位址加端口号,而UNIX Domain Socket的位址是一個socket類型的檔案在檔案系統中的路徑,這個socket檔案由bind()調用建立,如果調用bind()時該檔案已存在,則bind()錯誤傳回。

以下程式将UNIX Domain socket綁定到一個位址。

注意程式中的offsetof宏,它在stddef.h頭檔案中定義:

offsetof(struct sockaddr_un, sun_path)就是取sockaddr_un結構體的sun_path成員在結構體中的偏移,也就是從結構體的第幾個位元組開始是sun_path成員。想一想,這個宏是如何實作這一功能的?

該程式的運作結果如下。

以下是伺服器的listen子產品,與網絡socket程式設計類似,在bind之後要listen,表示通過bind的位址(也就是socket檔案)提供服務。

以下是伺服器的accept子產品,通過accept得到用戶端位址也應該是一個socket檔案,如果不是socket檔案就傳回錯誤碼,如果是socket檔案,在建立連接配接後這個檔案就沒有用了,調用unlink把它删掉,通過傳出參數uidptr傳回用戶端程式的user id。

以下是用戶端的connect子產品,與網絡socket程式設計不同的是,UNIX Domain Socket用戶端一般要顯式調用bind函數,而不依賴系統自動配置設定的位址。用戶端bind一個自己指定的socket檔案名的好處是,該檔案名可以包含用戶端的pid以便伺服器區分不同的用戶端。

下面是自己動手時間,請利用以上子產品編寫完整的用戶端/伺服器通訊的程式。

繼續閱讀