RPC使值在C中就地更改

背景

我正在为类编写基本的RPC客户端/服务器代码,其中一个要求是服务器端必须就地更改值。 最终目标是将矢量从客户端传递到服务器。 但由于我只是在学习RPC,所以我决定从基本的例子开始。 下面我有一个简单的代码,我在其中计算数字的平方。 对于这个例子,我想要就地改变结果。

问题

正如您在我的server.c看到的,我尝试就地更改了值。 但对于那些了解C的人来说,你已经可以看到我没有成功。 当调用./client localhost 4时,我的结果是4,因为我打印的是相同的值,我猜想它已经改变了,我原以为它不再是4.我怎样才能正确地改变原位值?

client.c

 #include  #include "square.h" int main(int argc, char **argv) { CLIENT *cl; square_in in; square_out *outp; if (argc != 3) //err_quit("usage: client  "); 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 */ 

服务器代码通常处于不同的进程中,即使在不同的机器上,因此它不是“在同一个地方”,因此它可以写入客户端的内存。 服务器接收的参数实际上是指向客户端传递的数据副本的指针。 因此服务器正在修改服务器进程的地址空间中的副本,这对客户端进程的地址空间中的原始数据没有影响。

有接口定义语言允许您将参数注释为out-params或in / out-params,因此生成器工具将编写期望服务器可以写入参数寻址的内存的代码,因此它应该将该数据发送回客户端并将其复制到客户端传入的内存中。 但是,您似乎正在使用ONC RPC或类似的,并且不清楚其RPC语言(RPCL)是否支持out-params。 见rpcgen ,第6.7节:

 procedure: type-ident procedure-ident "(" type-ident ")" "=" value 

请注意,支持out-params的IDL和关联的生成器工具不能真正允许服务器“就地”更改客户端的内存。 服务器的结果仍然必须在进程之间传输,通常通过网络传输。 从客户端和服务器代码的角度来看,这些只提供了外部参数的错觉。 所以你的要求是可疑的,也许没有明确说明。

编辑:

如果您确实需要服务器来修改客户端的内存:

  1. 确保服务器和客户端在同一台计算机上运行。
  2. 使用特定于操作系统的共享内存API(如shm_open()和mmap())将同一块物理内存映射到客户端和服务器的地址空间中。
  3. 使用RPC传输共享内存的标识符(名称)(而不是内存中的实际数据)并调用服务器的处理。
  4. 当客户端和服务器都打开并映射内存时,它们都有指针(可能在不同的地址空间中具有不同的值)到同一物理内存,因此服务器将能够读取客户端在那里写入的内容(没有复制)或传输),反之亦然。