Catalin Ichimov
Catalin Ichimov

Reputation: 81

How te send a string (char*) from server to client in onc-rpc

I hope that someone can help me. I am making a program that sends a long variable to from the client to the server and the last must respond with a string. I would like to point out i am using onc-rpc framework(sunRPC if i am not mistaking).

This is my current header => msg.x

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

My server stub must implement this function. I will not put all the code because it's a homework assigment.

My server stub => 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;
}

Needless to say the rest implementation works without the rpc. If i printf the string it works on a non rpc C file.

#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);
}

When i receive the server message i get seg fault. When i gdb, and step the client program at

result = fibcalc_1(whatToSend, cl); 

i get that the result address is 0x00

When i change the result type to let's say an int or long or w/e the result comes out nicely and the program works.

I would also like to point out that result is type char** because string is of type char * in onc-rpc and i came to realize that whatever variable the server function must return is the address of the return value.

I hope i explained well enough my problem. My first thought was that in the server function the char whatToSend[20] should be of type char * that i should allocate, but then how do i deallocate it?

Thank you in advance.

Upvotes: 1

Views: 3647

Answers (1)

Catalin Ichimov
Catalin Ichimov

Reputation: 81

My problem was that when i tried to send the result from the server stub function i did not realize that what i send must be saved on .data(static declaration) or heap(malloc). My resolve was to change in the server stub the following.

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;
}

In the client i tried to free the result after the function call. Although i have memory leaks it works now. Thank you @chux for your help

Upvotes: 1

Related Questions