Считать данные с оконечного устройства
#include <unistd.h>int readcond( int fd,void *buf,int n,int min,int time,int timeout );
libc
Функция readcond() считывает до n байт данных с оконечного устройства fd в буфер, на который указывает buf.
Эта функция является альтернативой функции read() для оконечных устройств, предоставляя дополнительные аргументы для операций чтения по времени. Эти дополнительные аргументы можно использовать для минимизации накладных расходов при работе с оконечными устройствами.
Три аргумента (min, time, и timeout),при использовании на оконечных устройствах в режиме RAW переопределяют поведение полей MIN и TIME только что определенной структуры termios (только на время вызова). Структура termios также определяет forwarding символ (в c_cc[VFWD]), который можно использовать для обхода min, time и timeout.
Обычный случай простого чтения приложением блокируется до тех пор, пока не будет доступен хотя бы один символ.
В случае, если указано несколько условий, чтение будет выполнено, когда будет выполнено любое из них.
MIN
Квалификатор MIN полезен, когда приложению известно количество символов, которое оно ожидает получить.
Любой протокол, который знает количество символов в наборе данных, может использовать MIN чтобы дождаться прибытия всего набора. Это значительно упрощает IPC и планирование процессов. MIN часто используется вместе с TIME или TIMEOUT. MIN является частью стандарта POSIX.
TIME
Квалификатор TIME полезен, когда приложение получает потоковые данные и желает получать уведомления, когда данные останавливаются или приостанавливаются. Время паузы составляет 1/10 секунды. TIME является частью стандарта POSIX.
TIMEOUT
Квалификатор TIMEOUT полезен, когда приложение знает, как долго ему следует ждать данных до истечения времени ожидания. Тайм-аут составляет «1/10» секунды.
Любой протокол, который знает количество символов в наборе данных, который он ожидает получить, может использовать TIMEOUT. Благодаря этому, в сочетании со скоростью передачи, можно предположить, когда данные должны быть доступны. Квалификатор действует как таймер для обнаружения недостающих символов. Его также можно использовать в интерактивных программах с вводом пользователя для отложенного чтения, если в течение заданного времени нет ответа.
TIMEOUT является расширением ЗОСРВ «Нейтрино» и не является частью стандарта POSIX.
FORWARD
Квалификатор FORWARD полезен, когда протокол имеет специальный разделительный символ. Например, протокол PPP, используемый для TCP/IP по последовательному каналу связи, начинает и заканчивает свои пакеты с помощью разделяюещего символа. При использовании в сочетании с TIMEOUT, символ FORWARD может значительно повысить эффективность реализации протокола. Процесс протокола будет получать полные наборы данных, а не символ за символом. В случае пропуска разделительного символа, для быстрого восстановления можно использовать TIMEOUT или TIME.
Это значительно сводит к минимуму объем работы IPC для ОС и приводит к гораздо более низкому использованию процессора при заданной скорости передачи данных TCP/IP. Интересно отметить, что PPP не содержит счетчика символов для своих фреймов. Без разделяющего символа, пришлось бы читать данные по одному символу за раз.
FORWARD является расширением ЗОСРВ «Нейтрино» и не явлется частью стандарта POSIX.
Чтобы использовать символ FORWARD, необходимо установить символ VFWD в поле c_cc структуры termios:
/* PPP forwarding character */const char fwd_char = 0x7e;#include <termios.h>...int fd;struct termios termio;...tcgetattr( fd, &termio );termio.c_cc[VFWD] = fwd_char;tcsetattr( fd, TCSANOW, &termio );
Следующая таблица объясняет взаимодействие min, time, и timeout:
min | time | timeout | Описание |
---|---|---|---|
0 | 0 | 0 | Немедленно возвращает столько байт, сколько доступно в данный момент (до n байт). |
M | 0 | 0 | Возвращает до n байт, только если доступно не менее M байт. |
0 | T | 0 | Возвращает до n байт, если доступен хотя бы один байт или истекло время T * 0.1 сек. |
M | T | 0 | Возвращает до n байт, если доступны либо M байт, или был получен хотя бы один байт, а время между получением двух соседних символов превышает T * 0.1 сек. |
0 | 0 | t | Для внутреннего использования. |
M | 0 | t | Возвращает до n байт, когда истекло t * 0.1 сек, или доступно M байт. |
0 | T | t | Для внутреннего использования. |
M | T | t | Возвращает до n байт, когда доступны M байт, или истекло время t * 0.1 , а символы не получены, или был получен хотя бы один байт, а время между получением двух соседних символов превышает T * 0.1 сек. |
Обратите внимание, что когда timeout равен нулю, поведение min и time точно такое же, как поведение параметров MIN и TIME для контролирующей структуры termios. Таким образом, readcond() может использоваться как более высокоскоростная альтернатива последовательным вызовам tcgetattr(), tcsetattr() и read() при работе с терминалом RAW ввода/вывода.
Случай (M, 0
, t) полезен для протоколов связи, которые не могут позволить себе блокироваться в ожидании данных, которые могут никогда не поступить.
Случай (M, T, ) предназначен для того, чтобы функция readcond() могла возвращаться при завершении пакета данных (как в случае (M, T, 0
)), но также и завершиться, если в течение некоторого периода времени пакет не был обнаружен.
Количество прочитанных байт.
Если возникла ошибка функция возвращает -1
, код ошибки записывается в errno.
O_NONBLOCK
установлен в этом fd, и процесс был бы заблокирован при попытке выполнить эту операцию. ЗОСРВ «Нейтрино»
errno, read(), tcgetattr(), tcsetattr(), struct termios
Предыдущий раздел: Описание API системной библиотеки