Как прекратить read (), когда EOF не встречается? - PullRequest
2 голосов
/ 08 февраля 2011

Я строю модель клиент / сервер, но использую сокеты, использую именованные каналы, с помощью mkfifo ().

Клиент записывает вывод в конвейер имен, и я считываю ввод на моем сервере, используя:

while ((n = read(fd_in, &newChar, 1)) == 1) { /* ... */ }

Я читаю по одному символу за раз, пока не встретлю два символа: <'CR'> <'LF'>. Я хотел бы сделать мой код таким образом, чтобы, если клиент через некоторое время, возможно, не завершился с <'CR'> <'LF'>, я мог отменить его и перейти к другому клиенту, иначе следующий клиент ждать, может быть, бесконечно.

Есть ли способ прекратить выполнение read ()? Если он не вернулся через 2 секунды, я мог бы сказать прерывание чтения и отбросить ранее прочитанные символы и начать чтение снова, пожалуйста?

Спасибо за вашу помощь,

Jary

Ответы [ 3 ]

4 голосов
/ 08 февраля 2011
#include <stdbool.h>
#include <poll.h>

do {
    ssize_t ret;
    struct pollfd ps = {.fd = fd_in, .events = POLLIN}; 

    if (poll(&ps, 1, 2000) < 0)
        break; /* kick client */
    ret = read(in_fd, ...);
    if (ret != 1)
        break;
    /* process read data */
} while (true);

Проверяет, есть ли данные для чтения;если нет 2000 мсек, делайте все, что хотите (например, отключите).

3 голосов
/ 08 февраля 2011

Попробуйте передать флаг O_NONBLOCK, когда вы open читаете конец FIFO.Это должно изменить поведение так, чтобы read сразу возвращался, даже если количество запрошенных символов отсутствует в конвейере.

1 голос
/ 08 февраля 2011

Чтобы обрабатывать несколько клиентов одновременно, вы должны установить неблокирующие дескрипторы файлов с помощью fcntl(), а затем использовать select() или poll() для блокировки, пока не появится ввод хотя бы на одном из них.

...