RPC已经值就地用C改变 [英] RPC to have values changed in-place in C

查看:150
本文介绍了RPC已经值就地用C改变的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

我写一个基本的RPC客户端/服务器code一类的要求之一是,在服务器端必须就地更改值。最终的目标是从客户端传递一个矢量到服务器。但由于我刚学RPC,我决定从基本的例子开始。下面我有一个简单的code中,我计算一个数值的平方。对于这个例子,我想就地已经改变结果。

问题

正如你可以在我的 server.c见,我试图改变就地值。但是,对于那些谁知道C,你已经可以看到我没有成功的情况下。当调用本地主机./client 4,我的结果是4,和因为我打印我supposely改变了相同的值,我希望它是不再4.如何正确更改就地价值?

client.c

 的#include< RPC / rpc.h>
#包括square.hINT
主(INT ARGC,字符** argv的)
  {
CLIENT * CL;
square_in的;
square_out * OUTP;如果(argc个!= 3)
    // err_quit(用法:客户<&主机GT;<整数值>中);
    出口(0);CL = clnt_create(的argv [1],SQUARE_PROG,SQUARE_VERS,TCP);in.arg1 =蒂(的argv [2]);
如果((OUTP = squareproc_1(安培;中,CL))== NULL)
    // err_quit(%S,clnt_sperror(CL,ARGV [1]));
   出口(0);的printf(结果:%ld的\\ n,in.arg1);
出口(0);
 }

server.c

  //服务器文件:server.c#包括RPC / rpc.h
#包括square.h
的#includestdio.h中
#包括stdlib.h中
#包括文件math.hsquare_out * squareproc_1_svc(square_in * INP,结构SVC_REQ * rqstp)
{    静态square_out出来;
    out.res1 = inp-> ARG1 * inp-> ARG1;
    inp-> ARG1 = out.res1;
    返回(安培;出);
}

square.x

 结构square_in {
 长ARG1;
 };结构square_out {
长RES1;
};节目SQUARE_PROG {
版本SQUARE_VERS {
square_out SQUAREPROC(square_in)= 1;
                    / *过程号= 1​​ * /
} = 1; / *版本号= 1 * /
} = 0x31230000; / *计划数= 0x31230000 * /


解决方案

服务器code是通常在不同的进程,甚至在不同的机器,所以它不是在同一个地方,例如,它可以写到客户端的存储器。服务器收到的参数实际上是一个指针的复制的客户端传递数据。所以服务器正在修改在服务器进程的地址空间,其具有在客户端进程的地址空间上的原始数据没有影响的副本。

有接口定义语言,让你标注参数外params中,输入/输出-PARAMS所以生成工具会写code,它预计该服务器可以写入由参数寻址的内存,因此它应该发送数据返回到客户端,并将其复制到由客户端传递到存储器。然而,似乎你正在使用ONC RPC或相似的,目前还不清楚它的RPC语言(RPCL)支持外PARAMS。请参见的rpcgen ,6.7节:

 步骤:
    类型IDENT过程的IDENT(类型IDENT)=值

请注意,支持外PARAMS一个IDL和相关的生成工具并没有真正允许服务器更改客户端的就地内存。服务器的结果仍必须进程之间传输的,常在网络上。这些只提供出则params的错觉从客户端和服务器code的视角。所以,你的要求是半信半疑的,也许不是明确规定。

编辑:

如果你真正需要的服务器修改客户端的内存:


  1. 确保在同一台机器上的服务器和客户端运行。

  2. 使用特定于操作系统的共享内存API,如的shm_open()和mmap()的物理内存相同的块映射到客户端和服务器的地址空间。

  3. 使用RPC来发送所述共享存储器的标识符(名称)(未在存储器中的实际数据),并调用服务器的处理。

  4. 当客户机和服务器已打开并映射的存储器,它们都具有指针(有可能与在不同的地址空间不同的值),以相同的物理存储器,以便服务器将能够读取哪些客户机写入那里(没有复制或传输),反之亦然。

background

I am writing a basic RPC client/server code for a class and one of the requirements is that the server side must change the values in-place. The final goal is to pass a vector from the client to the server. But since I am just learning RPC, I decided to start from basic examples. Below I have a simple code in which I compute the square of a number. For this example I'd like to change the result in-place already.

issue

As you can see in my server.c, I tried to change the value in-place. But for those who know C, you can already see I had no succcess. When calling ./client localhost 4, my result was 4, and since I am printing the same value I supposely changed, I had expected it to be no longer 4. How can I correctly change the value in-place?

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 */

解决方案

The server code is typically in a different process, even on a different machine, so it's not "in the same place" such that it could write into the client's memory. The argument the server receives is actually a pointer to a copy of the data passed by the client. So the server is modifying a copy in the server process's address space, which has no effect on the original data in the client process's address space.

There are interface definition languages that let you annotate parameters as out-params or in/out-params so the generator tool will write code that expects the server may write into the memory addressed by the parameter, so it should send that data back to the client and copy it into the memory passed in by the client. However, it appears you are using ONC RPC or similar, and it's not clear that its RPC Language (RPCL) supports out-params. See rpcgen, section 6.7:

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

Note that an IDL and associated generator tool that support out-params do not truly allow the server to change the client's memory "in-place". The server's results must still be transmitted between processes, often over the network. These provide only the illusion of out-params from the perspective of the client and server code. So your requirement is dubious, perhaps not clearly stated.

EDIT:

If you truly need the server to modify the client's memory:

  1. Ensure the server and client run on the same machine.
  2. Use OS-specific shared-memory APIs such as shm_open() and mmap() to map the same chunk of physical memory into the address spaces of both the client and the server.
  3. Use RPC to transmit the identifier (name) of the shared memory (not the actual data in the memory) and to invoke the server's processing.
  4. When both client and server have opened and mapped the memory, they both have pointers (likely with different values in the different address spaces) to the same physical memory, so the server will be able to read what the client writes there (with no copying or transmitting) and vice versa.

这篇关于RPC已经值就地用C改变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆