2011-10-13 84 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; 
} 

我還要補充一點,有一個命名管道,沒有必要保持關閉和再次打開它(儘管原子寫入的字節數有限制)。