RPC не может декодировать аргументы для транспорта TCP
Я работаю на многопоточном сервере RPC на основе примера с этой страницы:http://bderzhavets.blogspot.ca/2005/11/multithreaded-rpc-server-in-white-box.html
К сожалению, это не совсем работало из коробки, и после некоторой погони за ошибками я обнаружил, что серверу не удается декодировать аргументы (на основе кода возврата изsquareproc_2
). Казалось бы, выполнение на стороне сервера прекращается после вызоваsquareproc_2_svc
в функцииserv_request
, Увидетьcase: SQUAREPROC
в коде ниже от square_svc.c
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);
}
Вывод на стороне клиента:
yak@AcerPC:~/RPC/multithread_example$ ./ClientSQUARE localhost 2
squareproc_2 called
xdr_square_in result: 1
function call failed; code: 11
Вывод на стороне сервера:
yak@AcerPC:~/RPC/multithread_example$ sudo ./ServerSQUARE
creating threads
SQUAREPROC called
xdr_square_in result: 0
Как видите, xdr_square_in возвращает ЛОЖНЫЙ результат на стороне сервера. Вот квадрат.х
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, генерирую заглушки и код XDR сrpcgen -a -M
и компилировать сgcc
.
Эта ошибка возникает только при использовании TCP в качестве метода транспорта. Я могу получить результаты, используя UDP в качестве транспорта, но некоторые вызовы не выполняются, когда запросы от нескольких клиентов поступают одновременно. Я хотел бы иметь возможность поддерживать до 15 клиентов. Когда я попытался использовать UDP и 10 клиентов, 2 из 10 вызовов потерпели неудачу с другим кодом возврата изsquareproc_2
.