使用 rpcgen 从远程服务器返回字符串

Posted

技术标签:

【中文标题】使用 rpcgen 从远程服务器返回字符串【英文标题】:Returning string from a remote server using rpcgen 【发布时间】:2014-03-04 07:46:17 【问题描述】:

我正在学习 RPC 教程并学习 rpcgen 中的一些技术。我有使用 rpcgen 来添加、相乘不同数据类型的想法。

但是我还没有找到任何线索来说明如何在 .x 文件中声明一个返回字符串的函数。实际上我正在尝试构建一个返回随机字符串的程序(rand 字符串数组在服务器中)。

谁能告诉我如何处理这个问题?如果您向我提供有关此返回字符串/指针问题的任何教程,将会很有帮助。

提前谢谢你。

【问题讨论】:

【参考方案1】:

根据XDR protocol specification,你可以定义一个字符串类型,其中m是字符串的长度,以字节为单位:

该标准将 n(编号为 0 到 n -1)字节的字符串定义为编码为无符号整数的数字 n(如上所述),然后是字符串的 n 个字节。实现必须将每个字节视为 8 位透明数据。这允许使用任意字符集编码。字符串的字节 m 总是在字符串的字节 m +1 之前,而字符串的字节 0 总是在字符串的长度之后。如果 n 不是 4 的倍数,则 n 个字节后跟足够的(0 到 3)个剩余零字节 r,以使总字节数成为 4 的倍数。

string object<m>;

然后您可以定义一个字符串类型为str_t 的结构体作为变量之一:

typedef string str_t<255>;

struct my_result 
    str_t data;
;

然后在您的 .x 文件中,您可以在程序中定义一个 RPC,它返回一个类型为 my_result 的结构。由于 rpcgen 会给你一个指向这个结构(我称之为 res)的指针,你可以用prinf("%s\n", res-&gt;data); 打印消息。

program HELLO_PROG 
    version HELLO_VERSION 
        my_result abc() = 1;
     = 1;
 = 1000;

【讨论】:

【参考方案2】:

好的,回答原题(2岁多),第一个答案是正确的,但有点棘手。

在您的 .x 文件中,您使用内部字符串定义结构,之前已定义字符串的大小:

typedef string str_t<255>;

struct my_result 
    str_t data;
;
...

然后在 .x 文件上调用 rpcgen 以生成客户端和服务器存根以及 .xdr 文件:

$rpcgen -N *file.x*

现在,除了您假装使用远程功能的任何程序外,您还可以编译客户端和服务器。为此,我遵循了 ORACLE 网页中的“repcgen 教程”: https://docs.oracle.com/cd/E19683-01/816-1435/rpcgenpguide-21470/index.html

棘手的部分是,尽管您定义了一个大小为 m 的字符串(m 个字符的数组),但 rpcgen 和 .xdr 文件创建的是一个指向已分配内存的指针。像这样的:

.h 文件

typedef char *str_t;                                                                                                                        

struct my_result                                                               
    int res;                                                                    
    str_t data;                                                                 
;                                                                              
typedef struct my_result my_result;

.xdr 文件

bool_t xdr_str_t (XDR *xdrs, str_t *objp)                                              
                                                                               
    register int32_t *buf;                                                      

     if (!xdr_string (xdrs, objp, 255))                                         
         return FALSE;                                                          
    return TRUE;                                                                

因此,在您的服务器端使用此结构时,请注意它不是大小为 m 的字符串,而是一个 char 指针,您必须在使用它之前为其保留内存,否则您会收到相同的提示执行时比我错误:

Segmentation fault!

要在服务器上使用它,您可以编写:

static my_result response;                                                 
static char text[255];                                                      

memset(&response, '\0', sizeof(my_result));                                
memset(text, '\0', sizeof(text));                                           

response.data = text; 

然后您就可以明智地使用它了! :)

【讨论】:

以上是关于使用 rpcgen 从远程服务器返回字符串的主要内容,如果未能解决你的问题,请参考以下文章

结合 fuse 和 rpc 来列出远程目录

如何解析从远程服务器返回的 JSONP 数据

什么是协议编译器?为什么 rpcgen 被称为协议编译器?

C# 从FTP下载文件报错: 远程服务器返回错误: (550) 文件不可用(例如,未找到文件,无法访问文件)。

具有 30mb 输入字符串的 WCF 服务 - 远程服务器返回错误:(413)请求实体太大

远程服务器返回了意外相应:(413) Request Entity Too Large。