Чтение онлайн

на главную - закладки

Жанры

Основы программирования в Linux
Шрифт:

Выполните упражнение 15.8.

Упражнение 15.8. Функция
select

Далее для демонстрации применения функции select приведена программа select.c. Более сложный пример вы увидите чуть позже. Программа читает данные с клавиатуры (стандартный ввод — дескриптор 0) со временем ожидания 2,5 секунды. Данные читаются только тогда, когда ввод готов. Естественно расширить программу, включив в зависимости от характера приложения другие дескрипторы, такие как последовательные каналы (serial lines) и сокеты.

1. Начните как обычно с директив

include
и объявлений, а затем инициализируйте
inputs
для обработки ввода с клавиатуры:

#include <sys/types.h>

#include <sys/time.h>

#include <stdio.h>

#include <fcntl.h>

#include <sys/ioctl.h>

#include <unistd.h>

#include <stdlib.h>

int main {

 char buffer[128];

 int result, nread;

 fd_set inputs, testfds;

 struct timeval timeout;

 FD_ZERO(&inputs);

 FD_SET(0, &inputs);

2. Подождите ввод из файла stdin в течение максимум 2,5 секунд:

 while(1) {

testfds = inputs;

timeout.tv_sec = 2;

timeout.tv_usec = 500000;

result = select(FD_SETSIZE, &testfds, (fd_set *)NULL,

(fd_set*)NULL, &timeout);

3. Спустя это время проверьте

result
. Если ввода не было, программа выполнит цикл еще раз. Если в нем возникла ошибка, программа завершается:

switch(result) {

case 0:

printf("timeout\n");

break;

case -1:

perror("select");

exit(1);

4. Если во время ожидания у вас наблюдаются некоторые действия, связанные с файловым дескриптором, читайте ввод из stdin и выводите его при каждом получении символа EOL (конец строки), до нажатой комбинации клавиш <Ctrl>+<D>:

default:

if (FD_ISSET(0, &testfds)) {

ioctl(0, FIONREAD, &nread);

if (nread == 0) {

printf("keyboard done\n");

exit(0);

}

nread = read(0, buffer, nread);

buffer[nread] = 0;

printf("read %d from keyboard: %s", nread, buffer);

}

break;

}

 }

}

Во время выполнения эта программа каждые две с половиной секунды выводит строку

timeout
. Если вы набираете данные на клавиатуре, она читает файл стандартного ввода и отображает то, что было набрано. В большинстве командных оболочек ввод направляется в программу при нажатии пользователем клавиши <Enter> (или <Return>) или клавиш управляющей последовательности, поэтому программа будет отображать ввод каждый раз, когда вы нажимаете клавишу <Enter>. Учтите, что сама клавиша <Enter> тоже читается и обрабатывается как любой другой символ (попробуйте выполнить ввод без нажатия клавиши, введя ряд символов, за которыми следует комбинация <Ctrl>+<D>).

$ ./select

timeout

hello

read 6 from keyboard: hello

fred

read 5 from keyboard: fred

timeout

^D

keyboard done

$

Как это работает

Программа применяет вызов

select
для проверки состояния стандартного ввода. За счет корректировки значения времени ожидания программа каждые 2,5 секунды выводит сообщение об истечении времени ожидания. О нем свидетельствует возвращение 0 функцией
select
. При достижении конца файла дескриптор стандартного ввода помечается флагом как готовый к вводу, но при этом нет символов, предназначенных для считывания.

Множественные клиенты

Ваша простая серверная программа может выиграть от применения

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

Сервер может применять функцию

select
одновременно к сокету, ожидающему запросы на подключение, и к сокетам клиентских соединений. Как только активность зафиксирована, можно использовать макрос
FD_ISSET
для проверки в цикле всех возможных файловых дескрипторов и выявления активных среди них.

Если сокет, ожидающий запросов на подключение, готов к вводу, это означает, что клиент пытается подсоединиться, и вы можете вызывать функцию

accept
без риска блокировки. Если клиентский дескриптор указывает на готовность, это означает, что есть запрос клиента, ждущий, что вы сможете прочесть и обработать его. Чтение 0 байтов означает, что клиентский процесс завершился, и вы можете закрыть сокет и удалить его из множества своих дескрипторов.

Выполните упражнение 15.9.

Упражнение 15.9. Улучшенное клиент-серверное приложение

1. В финальный пример программы server5.с вы включите заголовочные файлы sys/time.h и sys/ioctl.h вместо signal.h, использованного в предыдущей программе, и объявите несколько дополнительных переменных для работы с вызовом

select
:

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <netinet/in.h>

#include <sys/time.h>

Поделиться:
Популярные книги

Хозяин Стужи 5

Петров Максим Николаевич
5. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
6.60
рейтинг книги
Хозяин Стужи 5

Эммануэль

Арсан Эммануэль
1. Эммануэль
Любовные романы:
эро литература
7.38
рейтинг книги
Эммануэль

Тринадцатый XII

NikL
12. Видящий смерть
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
7.00
рейтинг книги
Тринадцатый XII

Назад в СССР 5

Дамиров Рафаэль
5. Курсант
Фантастика:
попаданцы
альтернативная история
6.64
рейтинг книги
Назад в СССР 5

Наследие Маозари 9

Панежин Евгений
9. Наследие Маозари
Фантастика:
попаданцы
постапокалипсис
рпг
сказочная фантастика
6.25
рейтинг книги
Наследие Маозари 9

Первый среди равных. Книга II

Бор Жорж
2. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга II

На границе империй. Том 3

INDIGO
3. Фортуна дама переменчивая
Фантастика:
космическая фантастика
5.63
рейтинг книги
На границе империй. Том 3

Выйду замуж за спасателя

Рам Янка
1. Спасатели
Любовные романы:
современные любовные романы
7.00
рейтинг книги
Выйду замуж за спасателя

Слезы Эйдена 1

Владимиров Денис
11. Глэрд
Фантастика:
боевая фантастика
фэнтези
попаданцы
5.00
рейтинг книги
Слезы Эйдена 1

Кодекс Охотника. Книга XVII

Винокуров Юрий
17. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVII

Источники силы

Amazerak
4. Иной в голове
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Источники силы

Ученик. Книга вторая

Первухин Андрей Евгеньевич
2. Ученик
Фантастика:
фэнтези
5.40
рейтинг книги
Ученик. Книга вторая

Бояръ-Аниме. Газлайтер. Том 34

Володин Григорий Григорьевич
34. История Телепата
Фантастика:
фэнтези
боевая фантастика
аниме
5.00
рейтинг книги
Бояръ-Аниме. Газлайтер. Том 34

Распутье

Басаргин Иван Ульянович
Сибириада
Проза:
военная проза
историческая проза
5.00
рейтинг книги
Распутье