2014-02-10 29 views
0

我試圖將一個結構複製到一個進程中的FIFO,並嘗試使用另一個進程讀取FIFO中的數據以實現聊天。我的代碼編譯並運行,但結果不是我想要的。看來memcpy是我問題的源頭。試圖將結構複製到FIFO使用C

這裏是我的輸出:

測試@計算機-H:〜/桌面$ ./chat測試/ var/tmp中/ fifoA/var/tmp中/ fifoB

Arrancando線程1

Arrancando線程2

翅Arranca線程

/var/tmp中/ fifoA

/var/tmp中/ fifoB

FifoA打開

底注的printf

結構確定:測試,2

memcpy的邊的buff:@Test:@,0

結束髮送!

霍拉結束接收!

而其他終端:

測試@計算機-H:〜/桌面$ ./chat測試/ var/tmp中/ fifoB/var/tmp中/ fifoA Arrancando線程1

Arrancando線程2

翅片Arranca線程

/var/tmp中/ fifoA

/var/tmp中/ fifoB

FifoA打開

底注的printf

結構確定:測試,2

的memcpy bienEnd送!

BUFF:測試: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

當你正在傳輸的二進制數據以爲FIFO,則不應使用getline功能。你可以使用它,如果你是用fprintf函數寫的,女巫並非如此。

替換此:

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

此:

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

要足夠多。

此外,不要忘記檢查fread的回報。