Question

I'm trying to copy a structure to a fifo in a process, and trying to read that data from the fifo using another process in order to implement a chat. My code compiles and runs, but the outcome isn't the one i want. It seems that the memcpy is the cource of my problem.

Here's my output:

test@Computer-H:~/Desktop$ ./chat test /var/tmp/fifoA /var/tmp/fifoB

Arrancando thread1

Arrancando thread2

Fin Arranca threads

/var/tmp/fifoA

/var/tmp/fifoB

FifoA opened

antes printf

struct ok: test, 2

memcpy bien buff: �@�Test: �@�, 0

End send!

Hola end receive!

And on the other terminal:

test@Computer-H:~/Desktop$ ./chat test /var/tmp/fifoB /var/tmp/fifoA Arrancando thread1

Arrancando thread2

Fin Arranca threads

/var/tmp/fifoA

/var/tmp/fifoB

FifoA opened

antes printf

struct ok: test, 2

memcpy bienEnd send!

buff: � �Test: � �, 0

Hola end receive!

And my code:

#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <malloc.h> 
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>


#define MAX_CHARS_MSG 128
enum tipo_mensaje {
MENSAJE_NORMAL, /* Mensaje para transferir lineas de la conversacion entre ambos usuarios del chat*/
MENSAJE_NOMBRE, /* Tipo de mensaje reservado para enviar el nombre de usuario al otro extremo */
MENSAJE_FIN /* Tipo de mensaje que se env a por el FIFO cuando un extremo finaliza la comunicacion*/
};

struct mensaje_chat{
char contenido[MAX_CHARS_MSG]; // Cadena de caracteres ( acabada en '\0)
enum tipo_mensaje tipo;
};

//static const char* nombre = "test";

void *send(void *arg)
{
    int reading=1;
    int size = 0;
    char *readline;
    struct mensaje_chat *message = malloc(sizeof(struct mensaje_chat));
    void* buffer = malloc(sizeof(struct mensaje_chat));
    char moi[MAX_CHARS_MSG] = "test\0";
    const char* *fifo_send_path = arg;
    readline = malloc(size);
    printf("%s\n", *fifo_send_path);
    FILE *fifoAdesc = fopen(*fifo_send_path, "w");

    if( fifoAdesc == NULL){
        perror("Problema al abrir de la fifoA\n");
        return -1;
    }

    printf("FifoA opened\n");

    if(strlen(moi)<MAX_CHARS_MSG-1){
    printf("antes printf\n");
    snprintf(message->contenido, sizeof(message->contenido), "%s", &moi);
    message->tipo = MENSAJE_FIN;
    } else{
        printf("El nombre esta demasiado largo");
        return -1;
    }

    printf("struct ok: %s, %d\n", message->contenido, message->tipo);


    if(memcpy(buffer, message, sizeof(struct mensaje_chat)) == NULL ){
        perror("Problema de serialisacion\n");
        return -1;
    }

    printf("memcpy bien");

    if(fwrite( buffer, sizeof(struct mensaje_chat) ,1 , fifoAdesc) != 1){
                perror("Problema al escribir en la fifoA\n");
    }

    fclose(fifoAdesc);
    /**
    while(1){
        fifoAdesc = fopen(*fifo_send_path, "w");
        printf("\n>");
        int writtensize = getline(&readline, &size , stdin);
        if(fwrite( readline, strlen(readline), 1 , fifoAdesc) != 1){
                perror("Problema al escribir en la fifoA");
    }
        fclose(fifoAdesc);
        readline = NULL;
    }
    */

    free(readline);


    printf("End send!\n");

    return NULL;
}

void *receive(void *arg)
{
    int sending =1;
    int size = 0;
    struct mensaje_chat *message = malloc(sizeof(struct mensaje_chat));
    void* buffer = malloc(sizeof(struct mensaje_chat));
    char* sentline;
    const char* *fifo_receive_path = arg;
    sentline= malloc(size);
    printf("%s\n", *fifo_receive_path);
    FILE *fifoBdesc = fopen(*fifo_receive_path, "r");

    if( fifoBdesc == NULL){
        perror("Problema al abrir de la fifoB");
        return -1;
    }

    int readsize = getline( buffer, &size , fifoBdesc);
    message = (struct mensaje_chat*) buffer;
    printf(" buff: %s", (char*) buffer);
    printf("Test: %s, %d\n", (char*) message->contenido, message->tipo);

    fclose(fifoBdesc);

    /**while(1){

    fifoBdesc = fopen(*fifo_receive_path, "r");

    int readsize = getline( &sentline, &size , fifoBdesc);
    printf("\nAmigo> %s\n", sentline);
    fclose(fifoBdesc);
    sentline = NULL;
    }
    */
    free(sentline);

    printf("Hola end receive! \n");

    return NULL;
}

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

    pthread_t send_thread;
    pthread_t receive_thread;
    char* fifo_send_path;
    char* fifo_receive_path;

    if(argv[1] == NULL || argv[2] == NULL || argv[3] == NULL){
        printf("Necesitamos tres argumentos:\n");
        printf("./chat <nombre> <rutafifoA> <rutafifoB>\n");
        return -1;
    }

    fifo_send_path = argv[2];
    fifo_receive_path = argv[3];

    printf("Arrancando thread1\n");

    if( pthread_create(&send_thread, NULL, send, &fifo_send_path) != 0){
        perror("Problema al crear del thread de envio");
        return -2;
    }


    printf("Arrancando thread2\n");

    if( pthread_create(&receive_thread, NULL, receive, &fifo_receive_path) != 0){
        perror("Problema al crear del thread de recepcion");
        return -2;
    }

    printf("Fin Arranca threads\n");


    pthread_join(receive_thread, NULL);
    pthread_join(send_thread, NULL);

    return 0;
}
Was it helpful?

Solution

As you are transferring binary data thought the fifo, you should not use getline function. You could use it, if you were writing with fprintf function, witch is not the case.

Replace this:

int readsize = getline( buffer, &size , fifoBdesc);

for this:

int readsize = fread( buffer, sizeof(struct mensaje_chat) ,1 , fifoAdesc);

should be enought.

Also, don't forget to check the return of fread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top