c - 如何通过 RPC 发送数组?

标签 c linux unix rpc

我在使用 libtirpc 库通过 RPC 发送数组时遇到一些困难。在客户端-服务器 session 期间发送原语非常简单:

// 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);

xdrproc_t 函数签名是 bool_t (*xdrproc_t) (XDR *, void *, ...);xdr_int(3)xdr_long(3) 和其他原始序列化程序没有可变参数,因此可以直接使用 clnt_call(3)svc_getargs(3) 函数。然而,用于序列化可变长度数组的 xdr_array(3) 函数需要更多参数:

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

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];

但是,由于某些未知原因,只有数组的第一个元素(变量 a)被传输,而另一个包含垃圾。我做错了什么?

最佳答案

您错误地使用 xdr_array 有两个原因。

  1. 它只能处理动态分配的数组。
  2. 您正在尝试发送一个 int* 数组,就好像它是一个 int 数组一样。

正确的使用方法是这样的(从 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)) 
}

注意这些事情:

  1. p_array 是指向动态分配数组的指针。
  2. 它是一个 int 数组,而不是指针数组。
  3. 我们将 p_array 的地址传递给 xdr_array 以便在解码时它可以分配所需大小的数组并将其分配给 p_array.

如果你想要固定大小的数组,你需要使用 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)) 
}

请注意,您仍然不应在此处使用指针数组。

RPC 编译器会根据您的数据结构自动生成 XDR 过程,因此请考虑使用一个。

关于c - 如何通过 RPC 发送数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27460456/

相关文章:

c - 如何修复 char* 和 char** 的格式错误

c - 生成文件不工作? 'Nothing to be done for ' 生成文件'

linux - 给定两个 Linux 静态库,如何判断一个是否依赖于另一个?

linux - 将 bash 表达式传递给 AWK 以进行浮点运算

linux - BASH getopts 可选参数

c - 如果我想用 C 语言编写数组,如何将其放入函数中?

c - 仅运行预处理器但仅针对某些语句

linux - tcpdump 不显示 Wireshark 看到的数据包

linux - 无法读取 APIC 定时器寄存器

shell - 循环遍历以逗号分隔的 shell 变量