Я не могу понять результат этой программы чата - PullRequest
1 голос
/ 27 июня 2019

Итак, я создал простую сервер-клиентскую программу, которая может общаться друг с другом с помощью файла fifo (msgfifo).

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

Этого я не ожидал, так как ожидал напечатать его как целое предложение, но это не так, и я хочу знать, почему.

Когда я набираю что-то для отправки, процесс отправляет сигнал SIGUSR1 другому.

/* receive msg part */
/* added this using sigset(SIGUSR1, receiveSIGUSR1) */

void receiveSIGUSR1()
{
    char* msg = "\nIncoming Message from client...";
    char* msg2 = "\nClient : ";
    char buf[max_of_msg];
    int fd;
    write(1, msg, strlen(msg)+1);
    fflush(stdin);
    if( (fd = open("./msgpipe", O_RDONLY)) < 0)
    {   perror("open"); exit(1);    }
    read(fd, buf, max_of_msg);
    close(fd);
    write(1, msg2, strlen(msg2)+1);
    write(1, buf, strlen(buf)+1);
    flag = 0;
}

/*send msg part*/

while(1)
{
    flag = -1;
    printf("\nType what u want to send : ");
    scanf(" %s", msg);
    if(flag == 0)   continue;
    printf("msgtaken\n");
    fflush(stdin);
    if( (fd = open("./msgpipe", O_RDWR)) < 0)
    {   perror("exit"); exit(1);    }
    kill(clpid, 30);
    sleep(2);
    printf("Send message to Client..\n");
    write(fd, msg, max_of_msg);
    printf("Message Sent...\n");
}

Ожидаемый:

Клиент: Hello Server, это клиент

Фактический: / * сервер * /


Входящее сообщение от клиента ...
Привет
Входящее сообщение от клиента ...
это
входящее сообщение от клиента ...
есть
Входящее сообщение от клиента ...
клиент

Введите что вы хочу отправить:

/ клиент /


Введите то, что вы хотите отправить: Hello Server Это клиент
msgtaken
Отправить сообщение на сервер ..
Сообщение отправлено

Введите то, что вы хотите отправить: msgtaken
Отправить сообщение на сервер ..
Сообщение отправлено

Введите то, что вы хотите отправить: msgtaken
Отправить сообщение на сервер ..
Сообщение отправлено

Введите то, что вы хотите отправить : msgtaken
Отправить сообщение на сервер ..
Сообщение отправлено

Тип что вы хотите отправить: msgtaken
Отправить сообщение на сервер ..
Сообщение отправлено


Введите то, что вы хотите отправить:

1 Ответ

1 голос
/ 27 июня 2019

Это потому, что он принимает входные данные:

scanf(" %s", msg);

Давайте посмотрим на документацию scanf (выделено мое):

s: любое количество непробельных символов, останавливается на первом найденном пробельном символе .В конце сохраненной последовательности автоматически добавляется завершающий нулевой символ.

Именно поэтому он останавливается после Hello при отправке Hello Server this is client.Также обратите внимание на пробел в " %s", это означает, что он также будет игнорировать любые пробелы в начале ввода.Поэтому, когда он читает Server при следующем запуске цикла, он игнорирует пробел между Hello и Server.В результате он проходит цикл пять раз, и сообщения каждый раз: Hello, Server, this, is и client.

Вместо этого вы можете использовать getline:

char *message = NULL;
size_t length;
getline(&message, &length, stdin);
// use message
free(message);

Небольшое примечание: чтобы сделать ваш вызов scanf более безопасным, вы можете указать максимальный размер для ввода строки:

scanf(" %99s", msg);

Например, это может означать, что только 99 char может быть прочитано, плюс нулевой терминатор, для размера буфера 100. Таким образом, вы можете избежать неопределенного поведения, которое произойдет, если пользователь введетслишком большая строка для вашего буфера.

...