標籤:網路編程 rpc
RPC的全稱是Remote Procedure Call,它能夠在本地以函數調用的形式來實現網路操作,讓程式員集中關注於商務邏輯,不用關心底層的資料通訊。
這裡不會詳細講解RPC的原理,而是用一個簡單的echo伺服器的例子來說明如何使用RPC。
最早實現的RPC是sun rpc,現在它已經移植到了大多數作業系統。
使用RPC,程式員只需要關注客戶與伺服器之間資料傳送的格式以及如何遠程過程的定位,用戶端如何調用本地函數以調用遠程函數,伺服器遠程過程的實現。
1 用戶端與伺服器之間資料的互動
客戶與伺服器之間的資料傳送是通過定義一個.x檔案來實現的。在這個檔案中,程式員可以定義用戶端與伺服器互動的資料格式,例如,我們的echo.x內容如下:
struct hello {char text[256];};struct hello_echo {char text_echo[256];};program ECHO_PROG {version ECHO_VERS {hello_echo ECHOPROC(hello) = 1;} = 1;} = 0x31230000;
echo.x中定義了兩個結構體,一個是struct hello,它是用戶端向伺服器發送的資料,一個是struct hello_echo,它伺服器向用戶端發送的內容。下面定義了一個program ECHO_PROG,這個結構體用於遠程過程的定位,當用戶端發送資料過來時,伺服器需要確定調用哪個過程。
2 用戶端調用遠程過程
用戶端通過一個CLIENT的控制代碼來調用遠程過程:
CLIENT *cl;hello in;hello_echo *outp;if(argc != 3) {fprintf(stderr, "usage: client <hostname> <integer_value>\n");exit(0);}cl = clnt_create(argv[1], ECHO_PROG, ECHO_VERS, "tcp");strncpy(in.text, argv[2], strlen(argv[2]));in.text[strlen(argv[2])] = 0;if((outp = echoproc_1(&in, cl)) == NULL) {fprintf(stderr, "%s\n", clnt_sperror(cl, argv[1]));exit(0);}printf("result: %s\n", outp->text_echo);
首先定義一個CLIENT的指標和兩個用於發送資料和接收資料的參數,然後通過伺服器的IP地址和遠程過程的程式名以及版本號碼建立CLIENT,然後將命令列中的文本拷貝到發送參數hello in中,最後調用遠程過程echoproc_1(),其中echoproc是在program ECHO_PROG中定義的函數名,但是所有字母都小寫,1是該函數的版本號碼ECHO_VERS。
3 伺服器遠程過程的定義
伺服器的主程式通過rpcgen自動產生,程式員只需要定義遠程過程即可。
#include "echo.h"hello_echo *echoproc_1_svc(hello *inp, struct svc_req *rqstp){static hello_echo out;strncpy(out.text_echo, inp->text, strlen(inp->text));out.text_echo[strlen(inp->text)] = 0;return (&out);}
用戶端調用的遠程過程名是echoproc_1,而伺服器真正執行的遠程過程名則是echoproc_1_svc。
echoproc_1_svc()的參數和返回值已經確定了只要編寫函數體即可。
這裡的功能就是簡單的回射,因此,執行一個strncpy就行,最後返回一個hello_echo的地址,由於是局部變數的地址,因此,要用靜態局部變數。
4 程式的運行
首先對echo.x執行rpcgen得到標頭檔和伺服器的主程式:
rpcgen -C echo.x
然後分別對用戶端和伺服器端進行編譯:
gcc -o client client.c echo_clnt.c echo_xdr.cgcc -o server echo_svc.c server_func.c echo_xdr.c
執行伺服器:
./server
出現以下錯誤:
Cannot register service: RPC: Authentication error; why = Client credential too weak
意思是認證錯誤,以root許可權執行即可:
sudo ./server
然後執行用戶端:
./client 127.0.0.1 abc
第三個參數發送什麼,伺服器就回送什麼。
5 小結
RPC簡化了開發網路應用的步驟,只要定義通訊的資料和伺服器的遠程過程,就能夠在用戶端調用本地過程,RPC執行階段程式庫就能夠自動調用遠程過程。這對於開發大型的網路應用是十分方便的。