text使用线程或fork聊天应用程序

时间:2011-10-13 09:17:58

标签: c file-io fork

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

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

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


}

1 个答案:

答案 0 :(得分:0)

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

这是一个简单的命名管道示例,我保留尽可能多的代码:

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

我还应该补充一点,使用命名管道,不需要继续关闭并再次打开它(尽管原子写入的字节数有限制。)