UNIX: разработка сетевых приложений
Шрифт:
Простейший способ обработки подобной проблемы чтения-записи — это открытие двух стандартных потоков ввода-вывода для данного сокета: одного для чтения и другого для записи.
Пример: функция str_echo, использующая стандартный ввод-вывод
Сейчас мы модифицируем наш эхо-сервер TCP (см. листинг 5.2) для использования стандартного ввода-вывода вместо функций
Листинг 14.6. Функция str_echo, переписанная с использованием стандартного ввода-вывода
Если мы запустим наш сервер с этой версией функции
Здесь возникает проблема буферизации, поскольку сервер ничего не отражает, пока мы не введем наш символ конца файла. Выполняются следующие шаги:
Мы набираем первую строку ввода, и она отправляется серверу.
Сервер читает строку с помощью функции
Но стандартный поток ввода-вывода сервера полностью буферизованстандартной библиотекой ввода-вывода. Это значит, что библиотека копирует отраженную строку в свой стандартный буфер ввода-вывода
для этого потока, но не выдает содержимое буфера в дескриптор, поскольку буфер не заполнен.Мы набираем вторую строку ввода, и она отправляется серверу.
Сервер читает строку с помощью функции
Снова стандартная библиотека ввода-вывода сервера только копирует строку в свой буфер, но не выдает содержимое буфера в дескриптор, поскольку он не заполнен.
По тому же сценарию вводится третья строка.
Мы набираем наш символ конца файла, и функция
TCP сервера получает сегмент FIN, который читает функция
Функция
Библиотечная функция
Дочерний процесс сервера завершается, в результате чего закрывается его присоединенный сокет, клиенту отсылается сегмент FIN и заканчивается последовательность завершения соединения TCP.
Наша функция
Затем функция
Проблема здесь заключается в том, что буферизация на стороне сервера выполняется автоматически стандартной библиотекой ввода-вывода. Существует три типа буферизации, выполняемой стандартной библиотекой ввода-вывода.
1. Полная буферизация( fully buffered) означает, что ввод-вывод имеет место, только когда буфер заполнен, процесс явно вызывает функцию
2. Буферизация по строкам( line buffered) означает, что ввод-вывод имеет место, только когда встречается символ перевода строки, процесс вызывает функцию
3. Отсутствие буферизации( unbuffered) означает, что ввод-вывод имеет место каждый раз, когда вызывается функция стандартного ввода-вывода.
Большинство реализаций Unix стандартной библиотеки ввода-вывода используют следующие правила:
Стандартный поток ошибок никогда не буферизуется.
Стандартные потоки ввода и вывода буферизованы полностью, если они не подключены к терминальному устройству, в противном случае они буферизуются по строкам.