es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Problema de envío de estructura con fwrite() en el servidor TCP cliente.

Tengo una estructura de cuenta (como una cuenta bancaria) y quiero enviar la información de la cuenta al cliente cuando escribo “state” al inicio de la aplicación: ./client state luego el servidor debe enviar la información del cliente, sin embargo tengo un problema para enviar la estructura con la función fwrite,
he implementado esto en mi servidor.c

...
if(strcmp(buffer, "state") == 0){
    printf("enviando el estado de la cuenta...\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("número que escribí: %ld\n", nb_write);
    if(fflush(client_array[0].file)){
        syserr("error de fflush");
    }
}

y en mi client.c he escrito esto:

...
if(argc > 1){
    printf("argv[1]: %s\n", argv[1]);
    size_t nb_write = fwrite(argv[1], sizeof(*argv), strlen(argv[1]), fdc);

    printf("número que escribí: %ld\n", nb_write);

    if(fflush(fdc)){
        syserr("fflush");
    }
}
size_t nb_read = fread(&buffer, strlen(buffer), sizeof(BUFF_SIZE), fdc); // recepción de la estructura
printf("número que leí: %ld\n", nb_read);
printf("%s\n", buffer);

la aplicación cliente está esperando con el fread()

La salida de ./server:

número que leí: 4
state
enviando el estado de la cuenta...
account 1
número que escribí: 4
error de fflush: Búsqueda ilegal

Y cuando hago CTRL-C para detener el servidor, la aplicación cliente escribe algo extraño (quizás el contenido del búfer) y también se detiene la aplicación.

Creación de socket exitosa
¡Conexión exitosa!
argv[1]: state
número que escribí: 5
número que leí: 0
��E-�

Aquí está la estructura que quiero enviar:

struct account {
    char title[MAX_TITLE_LENGTH];
    struct user list_user[MAX_LIST_SIZE];
    // char description[140]; // por ejemplo, hotel, mercado, viaje
    int32_t total;
};

struct account a1;
/* CUENTA */
strcpy(a1.title, "cuenta 1");
a1.list_user[0] = u1;
a1.total = 0.0;

¿Cómo puedo arreglarlo para enviar la estructura correctamente en el descriptor de archivo del cliente y leerlo en el búfer de mi cliente?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Hay algunos problemas con la implementación actual:

    1. Al enviar la información de la cuenta desde el servidor al cliente, se utiliza la función memcpy para copiar el contenido de la estructura a1 al buffer. Sin embargo, esto no convierte realmente la estructura en un formato de cadena que se pueda enviar a través del socket. En su lugar, es necesario convertir la estructura en una cadena antes de enviarla. Una forma de hacer esto es utilizar la función sprintf para formatear la estructura en una cadena.
    2. En el código del cliente, se utiliza la función fwrite para escribir la cadena argv[1] en el descriptor de archivo fdc, lo cual no es correcto. En su lugar, la cadena argv[1] debe ser enviada a través del socket al servidor utilizando la función send.

    3. En el código del cliente, se utiliza la función fread para leer la información de la cuenta del descriptor de archivo fdc, lo cual nuevamente no es correcto. En su lugar, se debe utilizar la función recv para recibir la información a través del socket desde el servidor.

    Aquí hay una versión actualizada del código del servidor:

    if (strcmp(buffer, "state") == 0) {
        printf("enviando el estado de la cuenta...\n");
        char account_str[MAX_BUFF];
        sprintf(account_str, "%s;%d", a1.title, a1.total);
        size_t len = strlen(account_str) + 1;
        size_t nb_write = send(client_array[0].sock, account_str, len, 0);
        printf("número que escribí: %ld\n", nb_write);
        if (nb_write == -1) {
            syserr("error al enviar la información de la cuenta");
        }
    }
    

    Y aquí hay una versión actualizada del código del cliente:

    if (argc > 1) {
        printf("argv[1]: %s\n", argv[1]);
        size_t nb_write = send(sockfd, argv[1], strlen(argv[1]) + 1, 0);
        printf("número que escribí: %ld\n", nb_write);
    
        if (nb_write == -1) {
            syserr("error al enviar el argumento");
        }
    }
    
    size_t nb_read = recv(sockfd, buffer, MAX_BUFF, 0);
    printf("número que leí: %ld\n", nb_read);
    printf("%s\n", buffer);
    

    En este código actualizado, la información de la cuenta se convierte a un formato de cadena utilizando la función sprintf y se envía a través del socket utilizando la función send. El cliente lee la información de la cuenta desde el socket utilizando la función recv.

Comments are closed.