2011-10-13 112 views
-1

我面临一个问题,即我正在制作一个文本聊天程序。我会同时在两个不同的终端上运行这个程序。我在我的程序中使用的文件是在一个终端,我将写入数据,它将被存储在文件中,下一个终端将读取它,并显​​示相似的副本,反之亦然。使用线程或叉的文本聊天应用程序

我已经写了两个函数发送和接收现在我想我的发送和接收将同时工作,当我发送消息的同时我可以接收消息。我应该怎么做我已经尝试分叉,但我想我不知道何用它。我应该如何管理这个相同的文件是由两个进程访问它每次访问它两次任何建议或帮助谢谢 这是我的代码直到现在为止

#include<stdio.h> 
#include <sys/stat.h> 
#include<unistd.h> 
void send() 
    { 
    char message[256]; 
    fgets(message , 256 , stdin); 
    //printf("Message is : %s" , message); 
    FILE * f1; 
    f1= fopen("chatfile.txt", "w"); 
    if(f1== NULL) 
    { 
    printf("not open "); 
    } 
    fprintf(f1 , "%s" , message); 
    fclose(f1); 
    } 
    //------------------------------------------------------- 
void recieve() 
    { 
    char message[256]; 
    FILE * f1; 
    f1= fopen("chatfile.txt", "r"); 
    fgets(message , 256 , f1); 
    printf("Message is : %s" , message); 
    fclose(f1); 
    } 
    //------------------------------------------------------- 
int file_size() 
    { 
    struct stat st; 
    stat("chatfile.txt" , &st); 
    int size = st.st_size; 
    return size; 
    } 
    //------------------------------------------------------ 
int main() 
{ 
int size =0; 

//printf("%d" , getpid()); 
pid_t pid; 
pid = fork(); 
while(1) 
{ 
if(pid == 0) 

    { 
    printf("parent"); 
    send(); 
    } 
else 
    { 
    printf("child"); 
    recieve(); 
    } 
}  


} 
+0

我很乐意提供帮助,但是您和您需要的地方之间的差距是巨大的。您需要:1)发送和接收之间的同步2)检测文件创建的方法3)多于一个文件名4)接收以在显示它之后删除文件5)围绕发送/接收的循环构造6)用于分离位置的一些方式每个终端的文件7)... –

回答

0

您在这里遇到的问题是同步问题。您完全不知道发送完成的时间,接收者可以读取部分结果或根本不读取。您可能需要一种机制(如信号量),或者使用不同的介质(如命名管道)。你也应该考虑你的关机程序。

下面是一个简单的命名管道例子,在那里我有保留尽可能多的代码可能:

#include <stdio.h> 
#include <sys/stat.h> 
#include <unistd.h> 

#include <sys/types.h> 
#include <errno.h> 
#include <stdlib.h> 

/* Easier to alter if defined in one place 
    safere to put named-pipes in /tmp */ 
#define PIPENAME "/tmp/chatfile.pipe" 

/* An empty parameter list means no parameter 
    checking, not no parameters! */ 

void send(void) 
{ 
    char message[256]; 

    fgets(message , 256 , stdin); 

    FILE * f1; 
    f1= fopen(PIPENAME, "w"); 

    if(f1 == NULL) { 
     /* printf writes to stdout 
      perror writes to stderr, and includes the error */ 
     perror("not open "); 
     exit(1); 
    } 

    fprintf(f1 , "%s" , message); 
    fclose(f1); 
} 

//------------------------------------------------------- 

void recieve(void) 
{ 
    char message[256]; 
    FILE * f1; 
    f1= fopen(PIPENAME, "r"); 

    /* You should check EVERY open */ 
    if (f1 == NULL) { 
     perror("not open "); 
     exit(1); 
    } 

    fgets(message , 256 , f1); 
    printf("Message is : %s" , message); 
    fclose(f1); 
} 

//------------------------------------------------------ 

int main(int argc, char *argv[]) 
{ 
    int iResult = mkfifo(PIPENAME,0666); 
    if (iResult == -1 && errno != EEXIST) { 
     perror("Unable to create pipe"); 
     exit(1); 
    } 

    pid_t pid; 
    pid = fork(); 

    while(1) 
    { 
     if(pid == 0) { 
      printf("parent"); 
      send(); 
     } 
     else { 
      printf("child"); 
      recieve(); 
     } 
    } 
    return 0; 
} 

我还要补充一点,有一个命名管道,没有必要保持关闭和再次打开它(尽管原子写入的字节数有限制)。