TCP/IP 與 Internet 網路:第九章 RPC 高階程式介面  上一頁           下一頁

 

翻轉工作室:粘添壽

 

9-6 RPC 庫存函數

雖然規格檔經過 rpcgen 編譯後,會自動產生許多相關的 RPC 功能呼叫,但在許多情況下也需要使用者自行規劃使用。在 Unix/Linux 系統下,RPC 庫存函數(RPC Library)包含很多,一般而言都屬於比較低階(Low-level)的功能呼叫,我們只列出一些較常用的,如需要更詳細說明,請參考有關 RPC 的使用手冊(本書附錄的參考資料裡有列出)。

9-6-1 伺服端庫存函數

依照我們的範例,伺服端的 RPC 功能呼叫都存放於基礎檔(math_svc.c)內,一般較常用的有下列兩種:

(A)  svctcp_create()

此功能呼叫是希望核心系統開啟一個 RPC 傳輸連線,而此連線是建立在 TCP 傳輸點(Transport)上,又此 TCP 傳輸點是建立在 Socket 通訊端點上,程序語法如下:

SVCXPRT *svc

svc = svctcp_create(socket, sendsz, recvsz)

   int socket;

   u_int sendsz, recvsz;

svctcp_create() 呼叫所產生的 RPC 傳輸點(SVCXPRT)也稱之為『TCP-based RPC』,它是屬於緩衝器型的輸出/輸入裝置(Buffer I/O),因此必須定義接收緩衝器(recvsz)的大小,和傳送緩衝器的空間大小(sendsz),而該通訊端點是建立在已連接成功的 Socket 識別碼(socket ID)上。

(B) svcudp_create()

此功能呼叫也如同 svctcp_create() 一樣,但它是產生一個 UDP/IP-based 的傳輸點上,svcudp_create() 語法如下:

SVCXPTR *svc

svc = svcudp_create(socket)

   int socket;

此功能呼叫為非連接方式,因此不需要定義緩衝器大小。又 UDP 並未事先建立 Socket 的通訊端點,因此 socket 的內涵可定義為 RPC_ANY_SOCK,表示任意所產生的通訊端點。如果呼叫回應為 NULL,表示開啟失敗。

9-6-2 客戶端庫存函數

客戶端的功能呼叫不一定全然存放於基礎檔內,許多地方需要使用者在應用程式上編寫,因此,我們就必須特別去瞭解它。我們可以發現大部份的功能呼叫,都是針對一個特殊資料結構作處理,此資料結構為 CLIENT,表示 Client/Server 之間的通訊端點。以下介紹較常用的功能呼叫:

(A) clnt_create()

clnt_create() 為客戶端最主要的功能呼叫,主要功能是產生一個 Client/Server 的通訊連線,呼叫語法如下:

CLENT *clnt

clnt = clnt_create(host, prognum, versnum, protocol)

chat *host

u_long prognum, versnum;

char *protocol

參數中,host 表示連線主機;prognum 為程式號碼(在規格檔中宣告);versnum 是程式版本(也在規格檔中宣告);protocol 表示連線採用何種通訊協定;呼叫成功會傳回一個連線號碼,否則傳回空值(clnt = NULL)。由這個呼叫,我們大略可以瞭解它的連線方式,其表示用某一種通訊協定連結到遠端主機上,呼叫某一程式號碼下的一個程式版本。

參數中 protocol 表示連接方式,不同的網路環境有各自的連接方式,這牽涉到網路系統環境的安裝與管理,一般有下列幾種:

(1) "natpath"使用 Network Selection 通訊服務。clnt_create() 依照環境變數 NETPATH 的參數值連結,以第一個連結成功為主,其可能是連接導向或非連接方式。

(2) "circuit_n"使用 Network Selection 通訊服務,也是依照環境變數 NETPATH 中連接導向的通訊方式。

(3) "datagram_n"同上,但採用非連接方式。

(4) "visible"使用 Network Selection 通訊服務。clnt_create() 依照 /etc/netconfig 所設定的連接方式,但以第一個連接成功為主,可能是連接導向或非連接方式。

(5) "circuit_v"同上,但採用連接導向的通訊方式。

(6) "datagram_v"同上,但採用非連接方式。

(7) "tcp"使用 TCP 協定,亦是一般 Socket 系統呼叫連結方式。

(8) "udp"使用 UDP 協定,下層也是透過 Socket 系統呼叫連結。

如果採用 Network Selection 服務,在客戶端和伺服器上的主機電腦,必須安裝 Network Selection 通訊軟體。Network Selection 服務是將一般網路介面以變數名稱來代表,讓程式設計者存取網路資源,就如同讀取變數內容一樣方便。目前也有許多系統安裝 Network Selection,這讓讀者自行去探討,作者不再贅言。

在我們範例(math_req.c)中,clnt_create() 格式如下:

cl = clnt_create("linux-1", 0x20000001, 1, "tcp")

表示客戶端對伺服器端主機(linux-1 IP 位址),開啟 TCP 連線(也是 Socket Based),並呼叫程式號為 0x20000001 的遠端呼叫,而呼叫的程序版本為 1 內的遠端程序。程式號碼和版本號碼皆在標頭檔(math.x)內宣告。如果呼叫成功,便會傳回一個客戶端指標位址,如呼叫失敗便傳回空值(cl = NULL)。

(B) clnt_destroy()

此功能呼叫為關閉已開啟的 RPC 通訊連線,如果該連線是 TCP Based,同時會自動關閉相關的 Socket 端點。clnt_destroy() 的語法如下:

clnt_destroy(clnt)

CLIENT *clnt;

 (C) clnt_control()

此功能呼叫是針對已開啟成功的 RPC 連線作功能性設定,其中包含:溢時時間(time out)、UDP 重新傳送的溢時時間、雙方 Socket 的連線端點、以及其它狀態。clnt_control() 的語法如下:

bool_t bol;

bol = clnt_control(clnt, request, info)

CLIENT *clnt;

int request;

char *info;

其中參數 clnt 為欲控制的 RPC 連線;request 為控制項目;如果控制參數中需要傳送訊息,便存放在 info 變數內。如果呼叫成功便會回應 TRUE;否則回應 FALSE

一般控制項目(request)有下列幾種:

(1) CLSET_TIMEOUT設定整體的溢時時間(total time-out)。

(2) CLGET_TIMEOUT讀取已設定的整體溢時時間。

(3) CLGET_FD取得該 RPC 連線的 Socket 連線號碼。

(4) CLSET_FD_CLOSE設定當 clnt_destroy 執行時,同時關閉 Socket 連線。

(5) CLSET_FD_NCLOSE設定當 clnt_destroy 執行時,不關閉 Socket 連線。

(6) CLGET_SERVER_ADDR取得該 RPC 連線的伺服端 IP 位址。

另外針對 UDP 連線有下列兩個控制:

(1) CLSET_RETRY_TIMEOUT設定重試的溢時時間。

(2) CLGET_RETRY_TIMEOUT取得重試的溢時時間。

(D) clnt_call()

RPC 連線成功(clnt_create())後,再利用 clnt_call() 來呼叫遠端程序,一般 clnt_call() 函數都存放在客戶基礎檔(math_clnt.c)內,作為客戶端程式呼叫遠端程式之間的轉換,大多不希望使用者更改。我們由它的呼叫程序可大略瞭解 RPC 的運作方式,clnt_call() 語法如下:

enum clnt_stat

clnt_call(clnt, procnum, inproc, in, outproc, out, timeout)

CLIENT *clnt;

u_long procnum;

xdrproc_t inproc, outproc;

char *in, *out;

struct timeval timeout;

 

struct timeval {

long tv_sec;   /* seconds  */

long tv_usec;  /* microseconds */

};

我們用 math_clnt.c 範例中的:

clnt_call (clnt, ADD, (xdrproc_t) xdr_intpair, (caddr_t) argp, (xdrproc_t) xdr_int, (caddr_t) &clnt_res, TIMEOUT)

來說明 clnt_call() 中的參數值,其中參數 clnt RPC 連線識別值;procnum 為遠端程序號碼(ADD);inproc 為傳遞給遠端伺服端的 XDR 轉換函數((xdrproc_t) xdr_intpair);而 in 為傳遞參數((caddr_t) argp);相同的,outproc 是由遠端傳回來參數的 XDR 轉換函數((xdrproc_t) xdr_int);out 參數為遠端傳回之數值。

當執行 clnt_call() 後,會等待到系統回應才會返回(Blocking),如返回後結果RPC_SUCCESS 表示執行成功,否則會回應其它不成功的原因。如果系統沒有回應,則參數 timeout 表示溢時時間。

除了以上功能呼叫外,尚有下列三個較常用的函數,分別說明如下:

clnt_pcreateerror()當呼叫 clnt_create() 失敗時,此函數會將呼叫失敗原因的訊息,寫入標準錯誤輸出地方。

clnt_perror()執行介面呼叫失敗時,呼叫此函數,它會將失敗的原因表示在標準錯誤輸出。

clnt_freeres()此函數的功能是釋放程式介面執行時,所取用之記憶體。當呼叫介面程式後,執行此功能呼叫來釋放記憶體。

 

 

<GOTOP>