2014-10-29 138 views
1

我希望有人能幫助我。我正在製作一個程序,它將一個長變量從客戶端發送到服務器,最後一個必須使用字符串進行響應。我想指出我正在使用onc-rpc框架(sunRPC,如果我沒有錯)。如何從服務器發送一個字符串(char *)到客戶端onc-rpc

這是我目前的標題=> msg.x

//msg.x 
program MESSAGEPROG 
{ 
    version MESSAGEVERS 
    { 
     string FIBCALC(long) = 1; 
    } = 1; 
} = 0x20000001; 

我的服務器存根必須實現此功能。我不會把所有的代碼,因爲這是一個功課assigment。

我的服務器存根=> 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; 
} 

不用多說了REST實現作品,未經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); 
} 

當我收到服務器消息時,我得到seg故障。當我在

result = fibcalc_1(whatToSend, cl); 

用gdb,並加強客戶端程序,我得到這個結果的地址爲0x00

當我改變的結果類型,讓我們說一個int或長或W/E的結果出來很好,程序正常工作。

我還想指出結果是char **類型,因爲在onc-rpc中字符串類型爲char *,並且我意識到服務器函數必須返回的任何變量都是返回值的地址。

我希望我解釋得很好我的問題。我的第一個想法是,在服務器函數char whatToSend [20]應該是char *類型,我應該分配,但那麼我如何取消分配它?

預先感謝您。

+0

不應該代碼'char whatToSend [20]; ... return(&whatToSend);'在函數中。函數返回後,局部變量'whatToSend'變爲無效。 – chux 2014-10-29 01:23:35

+0

簡化'malloc()'的使用。建議'whatToSend = malloc(sizeof * whatToSend);'而不是'whatToSend =(long *)malloc(sizeof(long));'。 – chux 2014-10-29 01:25:31

+0

我使用了你的第一個建議,並使它成爲一個現在可以工作的指針,但它泄漏了內存,我不知道如何釋放它的指針。我將修改我的代碼以獲得第二個建議。 – 2014-10-29 01:31:05

回答

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的幫助

+0

我在c編程,並沒有意識到它是一個.x文件。 和a。x文件可以有一個字符串類型。 誰知道! – 2016-11-26 22:26:55

相關問題