Llinux程序間通訊 AF UNIX 套接字程式設計

2021-09-20 18:26:45 字數 3776 閱讀 6528

af_unix 位址系列(使用 af_unix 或 af_unix_ccsid 位址系列的套接字)可以是面向連線的(型別 sock_stream),也可以是無連線的(型別 sock_dgram)。兩種型別都很可靠,原因是沒有連線兩個程序的外部通訊函式。

unix 域資料報套接字的執行方式與 udp 資料報套接字有所不同。借助 udp 資料報套接字,客戶機程式就不必呼叫 bind() 函式,原因是系統會自動指定未使用的埠號。於是伺服器可將資料報傳送回該埠號。但是,使用 unix 域資料報套接字,系統不會自動指定客戶機的路徑名。因此,使用 unix 域資料報的所有客戶機程式必須呼叫bind() 函式。在客戶機的 bind() 上指定的精確路徑名就是傳遞至伺服器的路徑名。因此,如果客戶機指定相對路徑名(即,並非以 / 開頭的全限定路徑名),除非伺服器以同一當前目錄執行,否則它不能向客戶機傳送資料報。

應用程式可能對此位址系列使用的示例路徑名就是 /tmp/myserver 或 servers/thatserver。借助 servers/thatserver,可使用並非全限定(未指定 /)的路徑名。這表示該項在檔案系統層次結構中的位置應根據當前工作目錄確定。

注意:檔案系統中的路徑名是啟用了 nls 的。

下圖舉例說明了 af_unix 位址系列的客戶機/伺服器關係。有關將環境設定為使用 af_unix 位址系列的詳細資訊,參見套接字程式設計的先決條件。

在伺服器和客戶機 af_unix 位址系列示例程式中使用的套接字事件流。

socket() 函式返回表示端點的套接字描述符。該語句還標識將對此套接字使用帶有流傳輸(sock_stream)的 unix 位址系列。該函式返回表示端點的套接字描述符。還可使用socketpair() 函式初始化 unix 套接字。

af_unix 或 af_unix_ccsid 是支援 socketpair() 函式的唯一位址系列。socketpair() 函式返回未命名的和已連線的套接字描述符。

在建立套接字描述符之後,bind() 函式獲取套接字的唯一名稱。

unix 域套接字的命名空間由路徑名組成。當套接字程式呼叫 bind() 函式時,會在檔案系統目錄中建立一項。如果路徑名已存在,則bind() 失敗。因此,unix 域套接字程式應總是呼叫 unlink() 函式以在結束時除去該目錄項。

listen() 允許伺服器接受入局客戶機連線。在此示例中,儲備設定為 10。這表示系統將對 10 個入局連線請求排隊,然後才開始拒絕入局請求。

recv() 函式從客戶機應用程式接收資料。在此示例中,我們知道客戶機將傳送超過 250 位元組的資料。既然如此,就可以使用 so_rcvlowat 套接字選項指定在所有 250 位元組資料都到達之前不要喚醒recv()。

send()函式將資料回傳至客戶機。

close() 函式關閉所有開啟的套接字描述符。

unlink() 函式從檔案系統除去 unix 路徑名。

套接字事件流:使用 af_unix 位址系列的客戶機應用程式

示例:使用 af_unix 位址系列的客戶機應用程式使用以下函式呼叫序列:

socket() 函式返回表示端點的套接字描述符。該語句還標識將對此套接字使用帶有流傳輸(sock_stream)的 unix 位址系列。該函式返回表示端點的套接字描述符。還可使用socketpair() 函式初始化 unix 套接字。

af_unix 或 af_unix_ccsid 是支援 socketpair() 函式的唯一位址系列。socketpair() 函式返回未命名的和已連線的套接字描述符。

接收到套接字描述符後,使用 connect() 函式來建立與伺服器的連線。

send()函式傳送指定的 250 位元組資料,該資料是在伺服器應用程式中使用 so_rcvlowat 套接字選項指定的。

recv() 函式一直迴圈,直到所有 250 位元組資料都到達為止。

close() 函式關閉所有開啟的套接字描述符。

程式說明:

程式裡包含服務端和客戶端兩個程式,它們之間使用 af_unix 實現本機資料流通訊。使用 af_unix 域實際上是使用本地 socket 檔案來通訊。

伺服器端**:

引用#include

#include

#include

#include

#include

#include

int main (int argc, char *ar**)

printf ("the server is waiting for client data...\n");

for (i = 0, ch_send = '1'; i < 5; i++, ch_send++)

printf ("the character receiver from client is %c\n", ch_recv);

sleep (1);

if ((bytes = write (client_sockfd, &ch_send, 1)) == -1)

}close (client_sockfd);

unlink ("server socket");

}客戶端**:

引用#include

#include

#include

#include

#include

#include

int main (int argc, char *ar**)

address.sun_family = af_unix;

strcpy (address.sun_path, "server_socket");

len = sizeof (address);

/*向伺服器傳送連線請求*/

result = connect (sockfd, (struct sockaddr *)&address, len);

if (result == -1)

for (i = 0, ch_send = 'a'; i < 5; i++, ch_send++)

sleep (2); /*休息二秒鐘再發一次*/

if ((bytes = read (sockfd, &ch_recv, 1)) == -1)

printf ("receive from server data is %c\n", ch_recv);

}close (sockfd);

return (0);

}提示伺服器沒有準備好,連線被拒絕,從而直接退出程式。

如果伺服器和客戶端依次執行,可以在兩邊看到輸出:

伺服器端:

引用./sock_local_server 

server is waiting for client connect...

the server is waiting for client data...

the character receiver from client is a

the character receiver from client is b

the character receiver from client is c

the character receiver from client is d

the character receiver from client is e

客戶端:

引用./sock_local_client 

receive from server data is 1

receive from server data is 2

receive from server data is 3

receive from server data is 4

receive from server data is 5

php程序間通訊 yoc PHP程序間通訊

php是用c編寫的,因此它對系統底層api的操作與c很像,同大多數語言一樣,php程序間通訊的方式有以下幾種 訊息佇列,管道,共享記憶體,socket和訊號。本文是對這幾種通訊方式對整理 管道通訊pipe 管道用於承載簡稱之間的通訊資料。為了方便理解,可以將管道比作檔案,程序a將資料寫到管道p中,然...

程序間通訊

實現程序間資料共享除了常用的記憶體檔案對映外,對於一些非檔案的資料共享可以直接使用wm copydata。如果需要在程序a傳遞資料到程序b,簡單的實現如下 在程序a中 cstring strdatatosend t hello 需要傳遞的資料 hwnd hwndreceived 程序b的接收資料視窗...

程序間通訊

最近做專案遇到奇怪的問題,我在主線程中建立乙個工作執行緒。在工作執行緒中用sendmessage向主線程傳送訊息,通知主線程操作office 物件。getactiveobject時提示 hr 0x8001010d 因為應用程式正在傳送乙個輸入同步呼叫,所以無法執行傳出的呼叫。我把sendmessag...