Именованные каналы для реализации клиент-сервер. Как сервер будет различать два запроса от одного клиента

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

  Server.c:
    int main(void)
    {
         FILE *fp;
        char readbuf[80];

  /*Create the FIFO if it does not exist */
  umask(0);
  mknod(FIFO_FILE, S_IFIFO|0777, 0);
  while(1)
  {
   fp=fopen(FIFO_FILE, "r");
   fgets(readbuf,80, fp);
   fprintf(stderr,"Received string: %s\n", readbuf);
   fclose(fp);
   fprintf(stderr,"Finished iteration\n");
  }

 return(0);
 }

   Client.c:
     int main()
     {
       FILE *fp;
        char * message1="message1";
        char * message2="message2";
         if((fp = fopen(FIFO_FILE, "w+")) == NULL) {
                perror("fopen");
                     exit(1);
      }

  fprintf(stderr,"Trying to transfer the first message\n");
  fputs(message1, fp);
  fprintf(stderr,"Transferred the first message\n");
  fprintf(stderr,"Trying to transfer the second message\n");
  fputs(message2, fp);
  fprintf(stderr,"Trying to transfer the second message\n");
  fclose(fp);
  return(0);
   }

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


person Kunal    schedule 06.04.2016    source источник
comment
Каналы, именованные или анонимные, представляют собой неструктурированные потоки байтов. Если вы хотите, чтобы проходящие данные были организованы в какую-то более высокую структуру, такую ​​как последовательность отдельных сообщений, вам нужно реализовать это через какой-то протокол приложения. В самом простом случае вы можете отправлять сообщения в виде двоичного размера сообщения, за которым следует указанное количество байтов сообщения. Естественно, процессы на двух концах трубы должны согласовывать интерпретацию, чтобы коммуникация была успешной.   -  person John Bollinger    schedule 06.04.2016
comment
Возможно, вы хотели вместо этого использовать сокет домена Unix!   -  person Antti Haapala    schedule 06.04.2016
comment
Я знаю, что использование сокета упростит реализацию, но сейчас мне нужно реализовать через именованный канал.   -  person Kunal    schedule 06.04.2016
comment
Я попытался изменить код сервера на: while(1) { /*fp=fopen(FIFO_FILE, r);*/ /*fgets(readbuf,5, fp);*/ num=read(fd,readbuf,10 ); fprintf(stderr,Полученная строка: %s\n, readbuf); /*fclose(fp);*/ fprintf(stderr,Завершенная итерация\n); сон(20); } Я думал, что это заставит сервер заблокироваться, когда закончится чтение всего содержимого пайпа. Это не блокирует сервер, а переходит в бесконечный цикл.   -  person Kunal    schedule 06.04.2016


Ответы (1)


На уровне канала/потока нет информации о том, что представляет собой сообщение прикладного протокола. Однако есть два наиболее распространенных способа разграничения сообщений в потоке:

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

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

person Maxim Egorushkin    schedule 06.04.2016