我根据从该页面的例子工作一个多线程的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