текстовое приложение чата с использованием ветки или ветки - PullRequest
0 голосов
/ 13 октября 2011

У меня проблема с созданием текстового чата.и я буду запускать эту же программу в двух разных терминалах одновременно.Я использую файл в моей программе, который находится на одном терминале. Я запишу данные, которые будут сохранены в файле, а следующий терминал прочитает и отобразит аналогично.

У меня есть две функции отправки и получения.теперь я хочу, чтобы и мой отправитель и получатель работали одновременно, то есть когда я отправляю сообщение одновременно, я могу получать сообщение.что я должен делать, я пытался разветвиться, но я думаю, что я не знаю, как его использовать. и как мне управлять этим, так как к одному и тому же файлу обращаются два процесса, каждый обращается к нему два раза, любое предложение или помощь, спасибо, это мой коддо сих пор

#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 голосов
/ 13 октября 2011

Проблема у вас здесь одна из синхронизации. Вы не знаете, когда отправка была завершена, получатель мог прочитать частичные результаты или вообще ничего не прочитать. Вы либо нуждаетесь в механизме, таком как семафор, либо используете другой носитель, такой как именованный канал. Вы также должны принять во внимание ваше отключение 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;
}

Я должен также добавить, что для именованного канала нет необходимости продолжать закрывать и открывать его снова (хотя существует ограничение на количество байтов, которые записаны атомарно).

...