C 使用线程或fork的文本聊天应用程序

C 使用线程或fork的文本聊天应用程序,c,file-io,fork,C,File Io,Fork,我面临一个问题,我正在制作一个文本聊天程序。我将同时在两个不同的终端上运行相同的程序。我在程序中使用的文件位于一个终端,我将写入数据,它将存储在文件中,下一个终端将读取并显示它,反之亦然 我写了两个函数send和receive现在我想我的send和receive将在同一时间工作,也就是当我在发送消息的同时我可以接收消息。我应该怎么做我已经尝试过分叉,但我想我不知道怎么使用它。我应该如何管理它,因为同一个文件由两个进程访问,每个进程访问两次任何建议或帮助谢谢 这是到目前为止我的密码 #includ

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

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

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


}
#包括
#包括
#包括
作废发送()
{
字符消息[256];
fgets(信息,256,标准输入);
//printf(“消息为:%s”,消息);
文件*f1;
f1=fopen(“chatfile.txt”,“w”);
如果(f1==NULL)
{
printf(“未打开”);
}
fprintf(f1,“%s”,消息);
fclose(f1);
} 
//-------------------------------------------------------
无效接收()
{
字符消息[256];
文件*f1;
f1=fopen(“chatfile.txt”、“r”);
fgets(信息,256,f1);
printf(“消息为:%s”,消息);
fclose(f1);
}
//-------------------------------------------------------
int file_size()
{
结构统计;
stat(“chatfile.txt”和&st);
int size=st.st\u size;
返回大小;
}
//------------------------------------------------------
int main()
{
int size=0;
//printf(“%d”,getpid());
pid_t pid;
pid=fork();
而(1)
{
如果(pid==0)
{
printf(“母公司”);
send();
}
其他的
{
printf(“儿童”);
receive();
}
}     
}

这里的问题是同步。您不知道发送何时完成,接收者可能会读取部分结果,或者根本不读取任何结果。您要么需要一种机制,如信号量,要么使用另一种媒介,如命名管道。您还应该考虑到您的关机问题,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;
}
#包括
#包括
#包括
#包括
#包括
#包括
/*如果在一个地方定义,则更容易修改
安全地将命名管道放入/tmp*/
#定义PIPENAME“/tmp/chatfile.pipe”
/*空参数列表表示没有参数
检查,不是没有参数*/
作废发送(作废)
{
字符消息[256];
fgets(信息,256,标准输入);
文件*f1;
f1=fopen(管道名称,“w”);
如果(f1==NULL){
/*printf写入标准输出
perror写入stderr,并包含错误*/
perror(“非公开”);
出口(1);
}
fprintf(f1,“%s”,消息);
fclose(f1);
}
//-------------------------------------------------------
无效接收(无效)
{
字符消息[256];
文件*f1;
f1=fopen(管道名称,“r”);
/*你应该检查每一个开口*/
如果(f1==NULL){
perror(“非公开”);
出口(1);
}
fgets(信息,256,f1);
printf(“消息为:%s”,消息);
fclose(f1);
}
//------------------------------------------------------
int main(int argc,char*argv[])
{
int-iResult=mkfifo(管道名称,0666);
如果(iResult==-1&&errno!=EEXIST){
perror(“无法创建管道”);
出口(1);
}
pid_t pid;
pid=fork();
而(1)
{
如果(pid==0){
printf(“母公司”);
send();
}
否则{
printf(“儿童”);
receive();
}
}
返回0;
}

我还应该补充一点,对于命名管道,无需再次关闭和打开它(尽管原子写入的字节数有限制)。

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