简体   繁体   English

如何通过RPC发送数组?

[英]How do I send an array of over the RPC?

I have a bit of a difficulty sending arrays over the RPC using the libtirpc library. 使用libtirpc库通过RPC发送数组时,我有些困难。 Sending primitives during a client-server session is as easy as: 在客户机/服务器会话期间发送原语很容易:

// Client-side boilerplate
struct timeval tout = { 1, 0 };
int in = 42;
clnt_call (cln, 1, (xdrproc_t)xdr_int, (char*)&in,
    (xdrproc_t)xdr_void, NULL, tout);    

// Server-side boilerplate
int in;
svc_getargs (xprt, (xdrproc_t)xdr_int, (char*)&in);
assert (in == 42);

The xdrproc_t function signature is bool_t (*xdrproc_t) (XDR *, void *, ...); xdrproc_t函数签名为bool_t (*xdrproc_t) (XDR *, void *, ...); . The xdr_int(3) , xdr_long(3) and other primitive serializers have no variable arguments and so they can be used directly using the clnt_call(3) and svc_getargs(3) functions. xdr_int(3)xdr_long(3)和其他原始序列化器没有变量参数,因此可以使用clnt_call(3)svc_getargs(3)函数直接使用它们。 The xdr_array(3) function used to serialize variable length arrays, however, takes much more arguments: 但是,用于序列化可变长度数组的xdr_array(3)函数需要更多的参数:

bool_t xdr_array(XDR *xdrs, char **arrp, unsigned int *sizep,
                 unsigned int maxsize, unsigned int elsize,
                 xdrproc_t elproc);

The clnt_call(3) and svc_getargs(3) functions can't really pass these arguments to the functions, so creating wrapper functions seemed like the cleanest solution to the problem: clnt_call(3)svc_getargs(3)函数实际上无法将这些参数传递给这些函数,因此创建包装函数似乎是解决该问题的最简单方法:

// Client-side boilerplate
long a = 1, b = 2;
long * arr[] = { &a, &b };
unsigned int amount = sizeof(arr) / sizeof(long*);
bool_t xdr_array_wrapper (XDR * xdr, void * ptr) {
    return xdr_array (xdr, ptr, &amount, amount,
        sizeof(long), (xdrproc_t)xdr_long);
}

struct timeval tout = { 1, 0 };
long out;
clnt_call (cln, 1, (xdrproc_t)xdr_array_wrapper,
    (char*)arr, (xdrproc_t)xdr_long, (char*)&out, tout);

// Server-side boilerplate
long * arr[2];
unsigned int amount = sizeof(arr) / sizeof(long*);
bool_t xdr_array_wrapper (XDR * xdr, void * ptr) {
    return xdr_array (xdr, ptr, &amount, amount,
        sizeof(long), (xdrproc_t)xdr_long);
}
svc_getargs (xprt, (xdrproc_t)xdr_array_wrapper, (char*)arr);
long a = *arr[0], b = *arr[1];

However, for some unknown reason, only the first element of the array (the variable a ) is transferred and the other one contains garbage. 但是,由于某些未知的原因,仅传输数组的第一个元素(变量a ),而另一个包含垃圾。 What am I doing wrong? 我究竟做错了什么?

You are using xdr_array incorrectly for two reasons. 您使用xdr_array错误有两个原因。

  1. It can only handle dynamically allocated arrays. 它只能处理动态分配的数组。
  2. You are trying to send an array of int* as if it were an array of int . 您正在尝试发送一个int*数组,就好像它是一个int数组一样。

The correct way of using it goes like this (stolen from IBM and simplified, refer to the link for a more complete treatment): 正确的使用方式是这样的(从IBM窃取并简化,请参阅链接以获取更完整的处理):

typedef struct xarray
{
        int size;
        int *p_array;
} xarray ;

bool_t xdr_xarray(XDR *xdrs, xarray *p_xarray )
{
    return xdr_array(
                 xdrs,
                 (char**)(&(p_xarray->p_array)),
                 &(p_xarray->size),
                 MAX_INT,
                 sizeof(int),
                 (xdrproc_t)xdr_int)) 
}

Note these thinsg: 请注意以下thinsg:

  1. p_array is a pointer to a dynamically allocated array. p_array是指向动态分配数组的指针。
  2. It is an array of int , not of pointers. 它是int而不是指针的数组。
  3. We are passing an address of p_array to xdr_array so that on decoding it can allocate an array of the required size and assign it to p_array . 我们将p_array的地址p_arrayxdr_array以便在解码时它可以分配所需大小的数组并将其分配给p_array

If you want fixed-size arrays you need to use xdr_vector . 如果需要固定大小的数组,则需要使用xdr_vector

typedef struct xvector
{
        int vector[42];
} xarray ;

bool_t xdr_xvector(XDR *xdrs, xarray *p_xvector )
{
    return xdr_vector(
                 xdrs,
                 (char*)p_xvector->vector,
                 42,
                 sizeof(int),
                 (xdrproc_t)xdr_int)) 
}

Note you still should not use an array of pointers here. 注意,您仍然不应在此处使用指针数组。

An RPC compiler generates XDR procedures automatically from your data structures, so consider using one. RPC编译器会根据您的数据结构自动生成XDR过程,因此请考虑使用其中一种。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM