【问题标题】:RPC communication between Linux and SolarisLinux 和 Solaris 之间的 RPC 通信
【发布时间】:2013-04-05 08:17:42
【问题描述】:

我有一个在 Solaris 中运行的 RPC 服务器。我有一个在 Solaris 中运行良好的 RPC 客户端。
当我在 Ubuntu 中编译和运行相同的代码时,我在服务器中得到了Error decoding arguments

Solaris 使用 SunRPC (ONC RPC)。不知道如何找到 rpc 的版本。

Linux 和 Solaris 中可用的 RPC 有什么区别吗?
在 Solaris 和 Linux 中生成的 xdr 会不会不匹配?

我应该如何发现问题?

注意:代码不能发布

【问题讨论】:

  • 没有代码,很难确定实际问题,但我想到的一个主要问题是您是否始终记得进行字节顺序转换...
  • Solaris 不会将 ONC RPC 版本与操作系统分开,它只是该 Solaris 版本的版本,包含您为错误修复申请的任何补丁或包更新。
  • @twalberg 代码在 Solaris 中运行而不在 Linux 中运行有什么原因吗?我的意思是在 Linux 和 Solaris 中发送请求的方式?
  • Solaris 平台是 x86 还是 SPARC? SPARC 是大端,x86 是小端。如果您没有正确处理字节顺序,那么可以想象,您可以让 SPARC 能够与 SPARC 以及 x86 与 x86 对话,但不能在 SPARC 和 x86 之间对话,因为数据包中的字节顺序不同。
  • @twalberg 此行取自 SPARC 到 x86 指南。 Most of the modern protocols in corporate the External Data Representation (XDR) layer, which byte swaps data if needed during transfers RPC 使用 XDR,应该小心处理吧?

标签: linux solaris rpc


【解决方案1】:

@twalberg, @cppcoder 你解决问题了吗?我有同样的问题,但如果有帮助,我可以发布我的代码。部分代码是:

/* 现在分配一个 LoopListRequestStruct 并用请求数据填充它 */

llrs = malloc(sizeof(LoopListRequestStruct));

fill_llrs(llrs);

/* Now, make the client request to the bossServer   */

client_call_status = clnt_call(request_client, ModifyDhctState,
        (xdrproc_t)xdr_LoopListRequestStruct,
        (caddr_t)llrs, 
        (xdrproc_t)xdr_void,
        0,
        dummy_timeval
    );

void fill_llrs(LoopListRequestStruct* llrs) {

Descriptor_Loop* dl = 0;
DhctState_d *dhct_state_ptr = 0;
PackageAuthorization_d *pkg_auth_ptr = 0; 

llrs->TRANS_NUM = 999999;   /* strictly arbitraty, use whatever you want */
                                                    /* the bossServer simply passes this back in */
                                                    /* in the response you use it to match       */
                                                    /* request/response if you want or you can   */
                                                    /* choose to ignore it if you want           */

/* now set the response program number, this is the program number of  */
/* transient program that was set up using the svc_reg_utils.[ch]      */
/* it is that program that the response will be sent to                */

llrs->responseProgramNum = response_program_number; 

/* now allocate some memory for the data structures that will actually */
/* carry the request data */

llrs->ARG_PTR = malloc(sizeof(LoopListRequestArgs));

dl = llrs->ARG_PTR->loopList.Loop_List_val;

/* we are using a single descriptor loop at a time, this should always */
/* be the case */

llrs->ARG_PTR->loopList.Loop_List_len = 1;
llrs->ARG_PTR->loopList.Loop_List_val = malloc(sizeof(Descriptor_Loop));

/* now allocate memory and set the size for the ModifyDhctConfiguration */
/* this transaction always has 3 descriptors, the DhctMacAddr_d, the    */
/* DhctState_d, and the PackageAuthorization_d                          */

dl = llrs->ARG_PTR->loopList.Loop_List_val;
dl->Descriptor_Loop_len = 2;
dl->Descriptor_Loop_val = 
    malloc((2 * sizeof(Resource_descriptor_union)));

/* now, populate each descriptor */
/* the order doesn't really matter I'm just doing it in the order I    */
/* always have done */

/* first the mac address descriptor */

dl->Descriptor_Loop_val->type = 
    dhct_mac_addr_type;

strcpy(
    dl->Descriptor_Loop_val[0].Resource_descriptor_union_u.dhctMacAddr.dhctMacAddr,
    dhct_mac_addr
);

/* second the dhct state descriptor */

dl->Descriptor_Loop_val[1].type = 
    dhct_state_type;

dhct_state_ptr =
    &(dl->Descriptor_Loop_val[1].Resource_descriptor_union_u.dhctState);

if(dis_enable)
    dhct_state_ptr->disEnableFlag = DIS_Enabled;
else
    dhct_state_ptr->disEnableFlag = DIS_Disabled;

if(dms_enable)
    dhct_state_ptr->dmsEnableFlag = DMS_Enabled;
else
    dhct_state_ptr->dmsEnableFlag = DMS_Disabled;

if(analog_enable)
    dhct_state_ptr->analogEnableFlag = AEF_Enabled;
else
    dhct_state_ptr->analogEnableFlag = AEF_Disabled;

if(ippv_enable)
    dhct_state_ptr->ippvEnableFlag = IEF_Enabled;
else
    dhct_state_ptr->ippvEnableFlag = IEF_Disabled;

dhct_state_ptr->creditLimit = credit_limit;
dhct_state_ptr->maxIppvEvents = max_ippv_events;

/* we don't currently use the powerkey pin, instead we use an      */
/* application layer pin for purchases and blocking so always turn */   
/* pinEnable off */

dhct_state_ptr->pinEnable = PE_Disabled;
dhct_state_ptr->pin = 0;


if(fast_refresh_enable)
    dhct_state_ptr->fastRefreshFlag = FRF_Enabled;
else
    dhct_state_ptr->fastRefreshFlag = FRF_Disabled;

dhct_state_ptr->locationX = location_x;
dhct_state_ptr->locationY = location_y;

}

【讨论】:

    【解决方案2】:

    我在与同一软件集成时遇到了这个错误。 Linux 版本确实产生了不好的请求。这种行为的原因是空 c 字符串的序列化。 Glibc 版本的 SUN rpc 无法对其进行编码,xdr_string 返回零。但是您正在处理的示例将 'pin' 设置为 0。只需将 'pin' 替换为 "",或者在 xdr_string() 上创建一些包装器,示例将起作用。

    我的 PowerKey 示例补丁如下所示:

    <       if (!xdr_string(xdrs, objp, PIN_SZ))
    <               return (FALSE);
    <       return (TRUE);
    ---
    >     char *t = "";
    >     return  xdr_string(xdrs, *objp? objp : &t , PIN_SZ);
    

    当然,它可以变得更简单。一般来说,您应该修复生成代码的使用,在我的情况下,它是软件作者提供的示例源中的“pin”变量,必须在调用 xdr_string() 之前初始化。

    【讨论】:

    • 您指的是什么“别针”?我必须在哪里替换“”?
    • 你有上面Zeratul 代码的sn-p 吗?可能是我们在谈论不同的软件。我在处理 PowerKey 时解决了这个问题。无论如何,问题与您描述的完全一样。
    【解决方案3】:

    请注意,XDR 将处理字节序,但如果您使用应用特定的不透明字段,如果您自己不处理字节序,解码将会中断。确保整数作为 XDR 整数发送

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2016-05-04
      • 2012-03-01
      • 1970-01-01
      • 2011-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多