如何在 onc-rpc 中将字符串 (char*) 从服务器发送到客户端

Posted

技术标签:

【中文标题】如何在 onc-rpc 中将字符串 (char*) 从服务器发送到客户端【英文标题】:How te send a string (char*) from server to client in onc-rpc 【发布时间】:2014-10-29 01:02:42 【问题描述】:

我希望有人可以帮助我。我正在制作一个程序,它将一个长变量从客户端发送到服务器,最后一个必须用字符串响应。我想指出我正在使用 onc-rpc 框架(如果我没记错的话是 sunRPC)。

这是我当前的标题 => msg.x

//msg.x
program MESSAGEPROG

    version MESSAGEVERS
    
        string FIBCALC(long) = 1;
      = 1;
 = 0x20000001;

我的服务器存根必须实现这个功能。我不会放所有代码,因为这是一个家庭作业。

我的服务器存根 => server.c

#include <rpc/rpc.h>
#include <stdio.h>
#include <stdlb.h>
#include "msg.h"

char ** fibcalc_1_svc(whatToUse, dummy)
    long *whatToUse;
    struct svc_req *dummy;

    char whatToSend;

    whatToSend = (char **)malloc(sizeof(char*));
    *whatToSend = (char *)malloc(sizeof(char) * STRING_SIZE);

    //............

    return whatToSend;

不用说其余的实现都可以在没有 rpc 的情况下工作。如果我 printf 字符串,它适用于非 RPC C 文件。

#include <rpc/rpc.h>
#include <stdio.h>
#include <stdlb.h>
#include "msg.h"

int main(int argc, char *argv[])

CLIENT *cl;
char **result;
long *whatToSend, *test;
FILE *fout, *fin;


whatToSend = (long *)malloc(sizeof(long));
result = (char **)malloc(sizeof(char*));
*result = (char *)malloc(sizeof(char) * STRING_SIZE);

if(argc != 3)

    /* if arguments are not passed corectly
     * we print the following message and close with exit error
     */
    fprintf(stderr, "usage : ./%s [server ip] [fileIn]\n", argv[0]);
    exit(1);


cl = clnt_create(argv[1], 
                 MESSAGEPROG, 
                 MESSAGEVERS, 
                 "tcp");
if(cl == NULL)

    /* if no connection to server
     * we print the following message and close with exit error
     */
    clnt_pcreateerror(argv[1]);
    exit(1);



/* Sanity checks for file handle
 */
fin = fopen(argv[2],"r");
if (fin == NULL)

    fprintf(stderr, "Input handle could not be opened!\n");
    exit(1);
   

fout = fopen("out.txt", "w");
if (fout == NULL)

    fprintf(stderr, "Output handle could not be opened!\n");
    exit(1);



while(fscanf(fin, "%ld", whatToSend) != EOF)

    memset(*result, 0, STRING_SIZE);



    result = fibcalc_1(whatToSend, cl);

    if(result == NULL)
    
        /* Server did not respond
         */
        clnt_pcreateerror("localhost");
        exit(1);
    

    printf("%s\n", *result);


/* Sanity checks for closing the handles
 */
if(fclose(fin)) 

    fprintf(stderr, "Input handle could not be closed!!\n");
    exit(1);


if(fclose(fout)) 

    fprintf(stderr, "Output handle could not be closed!!\n");
    exit(1);


/* Free allocated memory
 */
free(whatToSend);
free(*result);
free(result);

exit(0);

当我收到服务器消息时,我得到了段错误。当我 gdb 时,在

处执行客户端程序
result = fibcalc_1(whatToSend, cl); 

我知道结果地址是0x00

当我将结果类型更改为 int 或 long 或 w/e 时,结果会很好地显示并且程序可以运行。

我还想指出,结果是 char** 类型,因为在 onc-rpc 中字符串是 char * 类型,我开始意识到服务器函数必须返回的任何变量都是返回值的地址。

我希望我能很好地解释我的问题。我的第一个想法是在服务器函数中 char whatToSend[20] 应该是我应该分配的 char * 类型,但是我该如何解除分配呢?

提前谢谢你。

【问题讨论】:

不应在函数中编码char whatToSend[20]; ... return (&amp;whatToSend);。一旦函数返回,局部变量whatToSend就失效了。 简化malloc() 的使用。建议使用whatToSend = malloc(sizeof *whatToSend); 而不是whatToSend = (long *)malloc(sizeof(long)); 我使用了您的第一个建议并将其设置为现在可以使用的指针,但它会泄漏内存,我不知道如何释放它的任何指针。我将根据第二个建议修改我的代码。 不清楚你是如何“让它成为指针”的。建议发布附加更新。 fibcalc_1_svc() 的变化是个问题。我不清楚该功能的作用。建议char *fibcalc_1_svc(long *whatToUse, struct svc_req *dummy) char *whatToSend; whatToSend = malloc(STRING_SIZE * sizeof *whatToSend); //............ return whatToSend; 【参考方案1】:

我的问题是,当我尝试从服务器存根函数发送结果时,我没有意识到我发送的内容必须保存在 .data(静态声明)或堆(malloc)上。我的决定是在服务器存根中更改以下内容。

char ** fibcalc_1_svc(whatToUse, dummy)
     long *whatToUse;
     struct svc_req *dummy;

     char whatToSend;

     whatToSend = (char **)malloc(sizeof(char*));
     *whatToSend = (char *)malloc(sizeof(char) * STRING_SIZE);

     //............

     return whatToSend;

在客户端中,我尝试在函数调用后释放结果。虽然我有内存泄漏,但它现在可以工作了。感谢@chux 的帮助

【讨论】:

我在 c 中对此进行了编程,但没有意识到它是一个 .x 文件。一个 .x 文件可以有一个字符串类型。谁知道!

以上是关于如何在 onc-rpc 中将字符串 (char*) 从服务器发送到客户端的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中将 char 值显示为字符串?

如何在 C++ 中将字符串转换为 const char[]

如何在 C++ 中将数组 char 复制到字符串或 int* (void *) 中? [关闭]

如何在 C++ 中将 char 指针附加到 std::string

如何在SAS(大学)中将char字符转换为日期?

如何在C中将char连接到char *?