RPC 在 C 中就地更改值
Posted
技术标签:
【中文标题】RPC 在 C 中就地更改值【英文标题】:RPC to have values changed in-place in C 【发布时间】:2016-07-05 12:29:40 【问题描述】:背景
我正在为一个类编写一个基本的 RPC 客户端/服务器代码,其中一个要求是服务器端必须就地更改值。最终目标是将向量从客户端传递到服务器。但由于我只是学习 RPC,所以我决定从基本示例开始。下面我有一个简单的代码,我在其中计算一个数字的平方。对于此示例,我想已经就地更改结果。
问题
正如您在我的server.c
中看到的,我尝试就地更改值。但是对于那些了解 C 的人来说,你已经可以看到我没有成功。调用 ./client localhost 4 时,我的结果是 4,由于我打印的值与我假设更改的相同,因此我预计它不再是 4。我怎样才能正确地就地更改值?
client.c
#include <rpc/rpc.h>
#include "square.h"
int
main(int argc, char **argv)
CLIENT *cl;
square_in in;
square_out *outp;
if (argc != 3)
//err_quit("usage: client <hostname> <integer-value>");
exit(0);
cl = clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "tcp");
in.arg1 = atol(argv[2]);
if ( (outp = squareproc_1(&in, cl)) == NULL)
//err_quit("%s", clnt_sperror(cl, argv[1]));
exit(0);
printf("result: %ld\n", in.arg1);
exit(0);
server.c
// SERVER FILE: server.c
#include"rpc/rpc.h"
#include"square.h"
#include"stdio.h"
#include"stdlib.h"
#include"math.h"
square_out *squareproc_1_svc(square_in *inp,struct svc_req *rqstp)
static square_out out;
out.res1 = inp->arg1 * inp->arg1;
inp->arg1 = out.res1;
return(&out);
square.x
struct square_in
long arg1;
;
struct square_out
long res1;
;
program SQUARE_PROG
version SQUARE_VERS
square_out SQUAREPROC(square_in) = 1;
/* procedure number = 1 */
= 1; /* version number = 1 */
= 0x31230000; /* program number = 0x31230000 */
【问题讨论】:
【参考方案1】:服务器代码通常在不同的进程中,即使在不同的机器上,所以它不是“在同一个地方”,因此它可以写入客户端的内存。服务器接收的参数实际上是一个指针,指向客户端传递的数据的副本。所以服务器正在修改服务器进程地址空间中的一个副本,这对客户端进程地址空间中的原始数据没有影响。
有些接口定义语言允许您将参数注释为输出参数或输入/输出参数,因此生成器工具将编写期望服务器可以写入参数寻址的内存的代码,因此它应该发送该数据返回给客户端,并将其复制到客户端传入的内存中。但是,您似乎正在使用 ONC RPC 或类似的,并且不清楚它的 RPC 语言 (RPCL) 是否支持 out-params。请参阅rpcgen,第 6.7 节:
procedure:
type-ident procedure-ident "(" type-ident ")" "=" value
请注意,支持 out-params 的 IDL 和相关的生成器工具并不真正允许服务器“就地”更改客户端的内存。服务器的结果仍然必须在进程之间传输,通常是通过网络传输。从客户端和服务器代码的角度来看,这些仅提供了超出参数的错觉。所以你的要求是可疑的,也许没有明确说明。
编辑:
如果确实需要服务器修改客户端的内存:
-
确保服务器和客户端在同一台机器上运行。
使用特定于操作系统的共享内存 API(例如 shm_open() 和 mmap())将同一块物理内存映射到客户端和服务器的地址空间。
使用 RPC 传输共享内存的标识符(名称)(不是内存中的实际数据)并调用服务器的处理。
当客户端和服务器都打开并映射内存时,它们都有指向同一物理内存的指针(可能在不同的地址空间中具有不同的值),因此服务器将能够读取客户端写入的内容(无需复制或传输),反之亦然。
【讨论】:
以上是关于RPC 在 C 中就地更改值的主要内容,如果未能解决你的问题,请参考以下文章