我根據從該頁面的例子工作一個多線程的RPC服務器上的解碼參數一段時間的錯誤,我發現服務器無法解碼參數(基於squareproc_2
的返回碼)。在函數serv_request
中調用squareproc_2_svc
後,服務器端的執行似乎停止。請參閱下面的代碼case: SQUAREPROC
從square_svc.cRPC不能用於TCP傳輸
void *serv_request(void *data)
{
struct thr_data *ptr_data = (struct thr_data *)data;
{
square_in argument;
square_out result;
bool_t retval;
xdrproc_t _xdr_argument, _xdr_result;
bool_t (*local)(char *, void *, struct svc_req *);
struct svc_req *rqstp = ptr_data->rqstp;
register SVCXPRT *transp = ptr_data->transp;
switch (rqstp->rq_proc) {
case NULLPROC:
printf("NULLPROC called\n");
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
return;
case SQUAREPROC:
_xdr_argument = (xdrproc_t) xdr_square_in;
_xdr_result = (xdrproc_t) xdr_square_out;
printf("_xdr_result = %ld\n",_xdr_result);
local = (bool_t (*) (char *, void *, struct svc_req *))squareproc_2_svc;
break;
default:
printf("default case executed");
svcerr_noproc (transp);
return;
}
memset ((void *)&argument, 0, sizeof (argument));
if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
printf("svc_getargs failed");
svcerr_decode (transp);
return;
}
retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp);
printf("serv_request result: %d\n",retval);
if (retval > 0 && !svc_sendreply(transp, (xdrproc_t) _xdr_result, (char *)&result))
{
printf("something happened...\n");
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "%s", "unable to free arguments");
exit (1);
}
if (!square_prog_2_freeresult (transp, _xdr_result, (caddr_t) &result))
fprintf (stderr, "%s", "unable to free results");
return;
}
}
這裏是squareproc_2_svc
從文件square_server.c實現:
bool_t squareproc_2_svc(square_in *inp,square_out *outp,struct svc_req *rqstp)
{
printf("Thread id = '%ld' started, arg = %ld\n",pthread_self(),inp->arg1);
sleep(5);
outp->res1=inp->arg1*inp->arg1;
printf("Thread id = '%ld' is done %ld \n",pthread_self(),outp->res1);
return(TRUE);
}
客戶端輸出:
[email protected]:~/RPC/multithread_example$ ./ClientSQUARE localhost 2
squareproc_2 called
xdr_square_in result: 1
function call failed; code: 11
服務器端輸出:
[email protected]:~/RPC/multithread_example$ sudo ./ServerSQUARE
creating threads
SQUAREPROC called
xdr_square_in result: 0
如您所見,xdr_square_in在服務器端返回FALSE結果。 這裏是square.x
struct square_in {
long arg1;
};
struct square_out {
long res1;
};
program SQUARE_PROG {
version SQUARE_VERS {
square_out SQUAREPROC(square_in) = 1;
} = 2 ;
} = 0x31230000;
和square_xdr.c
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include "square.h"
bool_t
xdr_square_in (XDR *xdrs, square_in *objp)
{
register int32_t *buf;
int retval;
if (!xdr_long (xdrs, &objp->arg1)) retval = FALSE;
else retval = TRUE;
printf("xdr_square_in result: %d\n",retval);
return retval;
}
bool_t
xdr_square_out (XDR *xdrs, square_out *objp)
{
register int32_t *buf;
int retval;
if (!xdr_long (xdrs, &objp->res1)) retval = FALSE;
else retval = TRUE;
printf("xdr_square_out result: %d\n",retval);
return retval;
}
我在Ubuntu 14.04 LTS工作,生成stub和XDR代碼rpcgen -a -M
,並與gcc
編譯。
該錯誤似乎只在使用TCP作爲傳輸方法時發生。我可以使用UDP作爲傳輸器獲得結果,但是當多個客戶端的請求同時到達時,某些調用會失敗。我希望能夠支持多達15個客戶。當我嘗試使用UDP和10個客戶端時,10個調用中的2個調用失敗,返回碼爲squareproc_2
。
爲什麼當他們只包含一個實體時創建兩個聯合'result'和'argument' – user3629249
我同意這看起來很奇怪,但我仍然在學習RPC,並且認爲有一些原因必須這樣。也就是說,我相信寫這個例子的人知道他們在做什麼,雖然讓我覺得很奇怪,但我無法找到或反對的理由,除了看起來很亂。 –
這是memset()的原型void * memset(void * s,int c,size_t n);'爲什麼代碼將第一個參數強制轉換爲'(char *)' – user3629249