Ошибка именованного конвейера

Извините за плохой заголовок, я не знал, как это объяснить просто. У меня есть 2 программы: сервер и клиент. Сервер создает именованный канал и ждет, чтобы что-то прочитать. Клиент подключается и отправляет сообщение в канал. Сервер проверяет часть сообщения, чтобы получить «тип» сообщения (в данном случае тип — «HELO»), читая символы с 4 по 8 отправленной строки. Если я отправлю «HELO», сервер напечатает «Type: HELO», как и ожидалось. Но если я отправлю сообщение с чем-то другим, оно не напечатает «Нет соответствия», как ожидалось: оно просто ничего не делает. Вот код:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define BUF_SIZE 256

char * getType(char * message){
  char* type = malloc(sizeof(char)*5);
  memcpy(type,&message[4],4);
  type[4] = '\0';
  return type;
}

int main(int argc, char* argv[]){

  mkfifo("tchatserv", 0666); 
  int fd = open("tchatserv", O_RDONLY);
  char buf[BUF_SIZE];
  int val;
  while(1){
    val = read(fd, buf , BUF_SIZE );
    if(val >0){
      char * type = getType(buf);
      if(strcmp("HELO",type) == 0){
        printf("Type: %s\n", type);
      }
      else{
        printf("no match");
      }
    }
  }
}

Вот клиент:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>

char * makeInt(int val){ 
  char* res = malloc(sizeof(char)*5);
  char l [5] = "";
  sprintf(l,"%d",val);
  if(val < 10){
    strcat(res,"000");
    strcat(res,l);
  }
  else if(val < 100){
    strcat(res,"00");
    strcat(res,l);
  }
  else if(val < 1000){
    strcat(res,"0");
    strcat(res,l);
  }
  else if( val < 10000){
    strcat(res,l);
  }
  return res;
}

char * makeString(char * ch, int final){ 
  int t = strlen(ch);   
  if(final == 1){
    t = t+4;
  }
  char * chaine = makeInt(t);
  strcat(chaine,ch);
  return chaine;
}
void connection(){ 

  printf("Pseudo:\n");
  char * pseudo = malloc(sizeof(char)*30);
  pseudo[0] = '\0';
  scanf("%s", pseudo);

  printf("Tube:\n");
  char * tube = malloc(sizeof(char)*30);
  tube[0] = '\0';
  scanf("%s", tube);

  char * message = malloc(sizeof(char)*100);
  char * type = "HELO";
  message[0] = '\0';
  strcat(message,type);
  pseudo = makeString(pseudo,0);
  strcat(message,pseudo);
  tube = makeString(tube,0);
  strcat(message,tube);
  message = makeString(message,1);
  printf("%s",message);
  int fd = open("tchatserv", O_WRONLY);
  write(fd,message,256);
}
int main(int argc, char* argv[]){
  connection();
  return 0;
}

РЕДАКТИРОВАТЬ: Когда я пытаюсь отправить что-то еще, кроме HELO, он не печатает «нет совпадения», но затем я отправляю HELO, и он печатает: «нет совпадения Тип: HELO», например, если первое «нет совпадения» застрял в канале вместо того, чтобы распечатать сразу, я не понимаю, почему.


person StuYYY    schedule 03.12.2016    source источник
comment
strcat(message,type); Это ошибка, приводящая к Undefined Behavior. message содержимое не инициализировано и содержит случайный мусор. strcat требуется завершающая строка NUL. Используйте strcpy или установите message[0]='\0'   -  person kaylum    schedule 04.12.2016
comment
Когда я отправляю HELO, кажется, что это работает. Я исправил проблему, хотя, но все еще та же проблема.   -  person StuYYY    schedule 04.12.2016
comment
Ваша функция makeString имеет возвращаемый тип char*, но ничего не возвращает. Это вызовет проблемы.   -  person Michael Albers    schedule 04.12.2016
comment
На самом деле это должно быть пустота, спасибо.   -  person StuYYY    schedule 04.12.2016
comment
УБ означает, что результат непредсказуем. Иногда может показаться, что он работает, но в других условиях он не работает. Никогда не подразумевайте, что в коде есть серьезная ошибка, но он все еще работает. Пожалуйста, обновите свой код с тем, что вы изменили, чтобы другим не нужно было указывать на это снова. И используйте отладчик.   -  person kaylum    schedule 04.12.2016
comment
Но вы не исправили ту же ошибку в других местах. strcat(res,"000"); где res содержимое - мусор.   -  person kaylum    schedule 04.12.2016
comment
char* res = malloc(sizeof(char)*4);, и он может содержать только строку из трех символов плюс завершающий символ NUL. Тем не менее, вы пишете строку из четырех символов.   -  person kaylum    schedule 04.12.2016
comment
Спасибо, только что отредактировал весь код. Также добавлена ​​информация об ошибке.   -  person StuYYY    schedule 04.12.2016


Ответы (1)


Когда я пытаюсь отправить что-то другое, кроме HELO, он не печатает «нет совпадения», но затем я отправляю HELO, и он печатает: «нет совпадения Тип: HELO», например, если первое «нет совпадения» застрял в канале вместо печатается сразу, я не понимаю, почему.

no match действительно застрял каким-то образом, но не в канале, а скорее в серверном буфере стандартного потока вывода, который предположительно линейно буферизуется, т.е. например, символы передаются (печатаются) когда встречается новая строка. Чтобы это исправить, просто измените printf("no match") на printf("no match\n") или puts("no match").

person Armali    schedule 19.03.2018