尝试使用C将结构复制到fifo时出现问题

时间:2014-02-10 10:41:10

标签: c struct chat memcpy fifo

我试图在一个进程中将结构复制到fifo,并尝试使用另一个进程从fifo读取该数据以实现聊天。我的代码编译并运行,但结果不是我想要的。似乎memcpy是我问题的源头。

这是我的输出:

  

测试@ Computer-H:〜/ Desktop $ ./chat test / var / tmp / fifoA / var / tmp / fifoB

     

Arrancando thread1

     

Arrancando thread2

     

Fin Arranca线程

     

的/ var / TMP / fifoA

     

的/ var / TMP / fifoB

     

FifoA开了

     

antes printf

     

struct ok:test,2

     

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

     

结束发送!

     

Hola结束了!

在另一个终端上:

  

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

     

Arrancando thread2

     

Fin Arranca线程

     

的/ var / TMP / fifoA

     

的/ var / TMP / fifoB

     

FifoA开了

     

antes printf

     

struct ok:test,2

     

memcpy bienEnd send!

     

buff:��Test:��,0

     

Hola结束了!

我的代码:

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

1 个答案:

答案 0 :(得分:1)

在传输二进制数据时,如果想要使用fifo,则不应使用getline函数。您可以使用它,如果您使用fprintf函数编写,则不是这样。

替换它:

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

为此:

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

另外,不要忘记检查fread的返回值。