RPC kann keine Argumente für den TCP-Transport dekodieren

Ich arbeite an einem Multithread-RPC-Server, basierend auf dem Beispiel auf dieser Seite:http: //bderzhavets.blogspot.ca/2005/11/multithreaded-rpc-server-in-white-box.htm

Leider hat es nicht ohne weiteres geklappt, und nachdem ich einige Zeit den Fehlern nachgegangen bin, habe ich festgestellt, dass der Server die Argumente nicht entschlüsseln kann (basierend auf dem Rückkehrcode vonsquareproc_2). Die Ausführung auf der Serverseite scheint nach dem Aufruf von @ anzuhaltsquareproc_2_svc in der Funktionserv_request. Sehencase: SQUAREPROC im Code unten von 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;
    }
}

Hier ist die Implementierung vonsquareproc_2_svc aus der Datei 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);
}

Client-seitige Ausgabe:

yak@AcerPC:~/RPC/multithread_example$ ./ClientSQUARE localhost 2
squareproc_2 called
xdr_square_in result: 1
function call failed; code: 11

Serverseitige Ausgabe:

yak@AcerPC:~/RPC/multithread_example$ sudo ./ServerSQUARE 
creating threads
SQUAREPROC called
xdr_square_in result: 0

Wie Sie sehen können, gibt xdr_square_in auf der Serverseite ein FALSE-Ergebnis zurück. Hier ist der 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;

und 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;
}

Ich arbeite in Ubuntu 14.04 LTS und erstelle Stubs und XDR-Code mitrpcgen -a -M und Kompilieren mitgcc.

Der Fehler scheint nur bei Verwendung von TCP als Transportmethode aufzutreten. Ich kann Ergebnisse mit UDP als Transport erhalten, aber einige Anrufe schlagen fehl, wenn Anforderungen von mehreren Clients gleichzeitig eintreffen. Ich möchte bis zu 15 Kunden betreuen können. Als ich versuchte, UDP und 10 Clients zu verwenden, schlugen 2 der 10 Aufrufe mit einem anderen Rückkehrcode als @ fehsquareproc_2.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage