Home > Software engineering >  problem of sending structure with fwrite() TCP Server client
problem of sending structure with fwrite() TCP Server client

Time:12-22

I have a structure of account (like a bank account) and i want to send the information of account to the client when i write "state" on starting of the app: ./client state then the server must to send the information of client, however i have a problem to send the structure with fwrite function, i have implemented this on my server.c

...
if(strcmp(buffer, "state") == 0) {
            printf("sending the state of account...\n");
            memcpy(buffer, &a1, sizeof(a1));
            printf("%s\n", buffer);
            size_t nb_write = fwrite(buffer, sizeof(char), sizeof(MAX_BUFF), client_array[0].file);
            printf("number i write: %ld\n", nb_write);
            if(fflush(client_array[0].file)){
                syserr("error of fflush");
            }
        }

and on my client.c i have written this:

...
 if(argc > 1){
        printf("argv[1]: %s\n", argv[1]);
        size_t nb_write = fwrite(argv[1], sizeof(*argv), strlen(argv[1]), fdc);
    
        printf("number i write: %ld\n", nb_write);
    
        if(fflush(fdc)){
            syserr("fflush");
        }
    }
    size_t nbread = fread(&buffer, strlen(buffer), sizeof(BUFF_SIZE), fdc); // reception of structure
    printf("number i read: %ld\n", nbread);
    printf("%s\n", buffer);

the app client is waiting with the fread()

the output of ./server:

number i read: 4
state
sending the state of account...
account 1
number i write: 4
error of fflush: Illegal seek

And when i do CTRL-C to stop the server, the app client write something strange (the content of the buffer maybe) and the app is stopping also.

Socket creation successful
Connection successful !
argv[1]: state
number i write: 5
number i read: 0
��E-�

here the structure i want to send:

    struct account{
        char title[MAX_TITLE_LENGTH];
        struct user list_user[MAX_LIST_SIZE];
        // char description[140]; // for example hotel, market, travel
        int32_t total;
    };
    
    struct account a1;
    /* ACCOUNT */
    strcpy(a1.title, "account 1");
    a1.list_user[0] = u1;
    a1.total = 0.0;

How can i fix it to send the structure correctly on the fd of client and read it on my client's buffer

CodePudding user response:

I see many mistakes in this code:

  • sizeof(MAX_BUFF) in the server's fwrite() is wrong. You need to use either just MAX_BUFF or sizeof(buffer) instead.

  • sizeof(*argv) in the client's fwrite() is wrong. *argv (aka argv[0]) is a char*, not a char. You need to use sizeof(char) ie 1 instead.

  • the client is not sending either the command's null terminator or the command's length to the server, so how do you expect the server to know when the end of the command is reached? There is no 1:1 relationship between writes and reads in TCP, so you have to account for the data's actual size one way or the other.

  • when the client calls fread(), &buffer, strlen(buffer), and sizeof(BUFF_SIZE) are all wrong. While &buffer may work, strlen(buffer) certainly will not, as the buffer hasn't been populated with a null-terminated string, so you need to use sizeof(char) ie 1 instead. And sizeof(BUFF_SIZE) needs to be either just BUFF_SIZE or sizeof(buffer) instead.

  • printf("%s\n", buffer); in both client and server is wrong, since buffer is clearly not a null-terminated string.

  • the client is expecting to receive the struct even if the client doesn't request the server to send it.

With that said, try something more like this:

...
char *cmd = NULL;
size_t size;
ssize_t len;

if ((len = getdelim(&cmd, &size, '\0', client_array[0].file)) < 0) {
    syserr("error of getdelim");
    fclose(client_array[0].file);
}
else if (strcmp(cmd, "state") == 0) {
    printf("sending the state of account...\n");
    uint32_t size = htonl(sizeof(a1));
    size_t nb_write = fwrite(&size, sizeof(size), 1, client_array[0].file);
    if (nb_write == 1) {
        nb_write = fwrite(&a1, sizeof(a1), 1, client_array[0].file);
    }
    if (nb_write < 1) {
        syserr("error of fwrite");
        fclose(client_array[0].file);
    }
    else {
        printf("number i write: %ld\n", sizeof(size)   sizeof(a1));
        if (fflush(client_array[0].file) != 0) {
            syserr("error of fflush");
        }
    }
}
free(cmd);
...
if (argc > 1) {
    printf("argv[1]: %s\n", argv[1]);

    if (fwrite(argv[1], strlen(argv[1]) 1, 1, fdc) < 1) {
        syserr("error of fwrite");
        fclose(fdc);
    }
    else if (fflush(fdc) != 0) {
        syserr("fflush");
    }

    uint32_t size;
    size_t nb_read = fread(&size, sizeof(size), 1, fdc);
    if (nb_read == 1) {
        size = ntohl(size);
        nb_read = fread(buffer, size, 1, fdc);
    }   
    if (nb_read < 1) {
        syserr("error of fread");
        fclose(fdc);
    }
    else {
        printf("number i read: %ld\n", sizeof(size)   size);
        printf("%.*s\n", size, buffer);
    }
}

CodePudding user response:

To read something send by the client i have this on my server.c

        size_t nbread;
        client_array[0].file = fdopen(client_array[0].fd, "w ");
        nbread = fread(buffer, sizeof(char), 1, client_array[0].file);
        if(nbread < 1){
            syserr("fread");
            return true;
        }
        printf("number i read: %ld\n", nbread);
        printf("%s\n",buffer);

And I realized the reading have also a problem. If somebody can help me

  • Related