14.8. Сокеты и стандартный ввод-вывод
14.8. Сокеты и стандартный ввод-вывод
Во всех наших примерах мы применяли то, что иногда называется вводом-выводом Unix, вызывали функции read и write и их разновидности (recv, send и т.д.). Эти функции работают с дескрипторами и обычно реализуются как системные вызовы внутри ядра Unix.
Другой метод выполнения ввода-вывода заключается в использовании стандартной библиотеки ввода-вывода. Она задается стандартом ANSI С и была задумана как библиотека, совместимая с не-Unix системами, поддерживающими ANSI С. Стандартная библиотека ввода-вывода обрабатывает некоторые моменты, о которых мы должны заботиться сами при использовании функций ввода- вывода Unix, таких как автоматическая буферизация потоков ввода и вывода. К сожалению, ее обработка буферизации потока может представить новый ряд проблем, о которых следует помнить. Глава 5 [110] подробно описывает стандартную библиотеку ввода-вывода, а в [92] представлена полная реализация стандартной библиотеки ввода-вывода и ее обсуждение.
ПРИМЕЧАНИЕ
При обсуждении стандартной библиотеки ввода-вывода используется термин «поток» в выражениях типа «мы открываем поток ввода» или «мы очищаем поток вывода». Не путайте это с подсистемой потоков STREAMS, которую мы обсуждаем в главе 31.
Стандартная библиотека ввода-вывода может использоваться с сокетами, но есть несколько моментов, которые необходимо при этом учитывать.
? Стандартный поток ввода-вывода может быть создан из любого дескриптора при помощи вызова функции fdopen. Аналогично, имея стандартный поток ввода-вывода, мы можем получить соответствующий дескриптор, вызывая функцию fileno. С функцией fileno мы впервые встретились в листинге 6.1, когда мы хотели вызвать функцию select для стандартного потока ввода-вывода. Функция select работает только с дескрипторами, поэтому нам необходимо было получить дескриптор для стандартного потока ввода-вывода.
? Сокеты TCP и UDP являются двусторонними. Стандартные потоки ввода- вывода также могут быть двусторонними: мы просто открываем поток типа r+, что означает чтение-запись. Но в таком потоке за функцией вывода не может следовать функция ввода, если между ними нет вызова функции fflush, fseek, fsetpots или rewind. Аналогично, за функцией вывода не может следовать функция ввода, если между ними нет вызова функции fseek, fsetpots, rewind, в том случае, когда при вводе не получен признак конца файла. Проблема с последними тремя функциями состоит в том, что все они вызывают функцию lseek, которая не работает с сокетами.
? Простейший способ обработки подобной проблемы чтения-записи — это открытие двух стандартных потоков ввода-вывода для данного сокета: одного для чтения и другого для записи.
Данный текст является ознакомительным фрагментом.