UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Стандартная библиотека ввода-вывода может использоваться с сокетами, но есть несколько моментов, которые необходимо при этом учитывать.
■ Стандартный поток ввода-вывода может быть создан из любого дескриптора при помощи вызова функции
fdopen
fileno
fileno
select
select
■ Сокеты TCP и UDP являются двусторонними. Стандартные потоки ввода- вывода также могут быть двусторонними: мы просто открываем поток типа
r+
fflush
fseek
fsetpots
rewind
fseek
fsetpots
rewind
lseek
■ Простейший способ обработки подобной проблемы чтения-записи — это открытие двух стандартных потоков ввода-вывода для данного сокета: одного для чтения и другого для записи.
Пример: функция str_echo, использующая стандартный ввод-вывод
Сейчас мы модифицируем наш эхо-сервер TCP (см. листинг 5.2) для использования стандартного ввода-вывода вместо функций
readline
writen
str_echo
Листинг 14.6. Функция str_echo, переписанная с использованием стандартного ввода-вывода
//advio/str_echo_stdiо02.с
1 #include "unp.h"
2 void
3 str_echo(int sockfd)
4 {
5 char line[MAXLINE];
6 FILE *fpin, *fpout;
7 fpin = Fdopen(sockfd, "r");
8 fpout = Fdopen(sockfd, "w");
9 while (Fgets(line, MAXLINE, fpin) != NULL)
10 Fputs(line, fpout);
11 }
7-10
fdopen
readline
writen
fgets
fputs
Если мы запустим наш сервер с этой версией функции
str_echo
hpux % <b>tcpcli02 206.168.112.96</b>
<b>hello, world</b> <i>мы набираем эту строку, но не получаем отражения</i>
<b>and hi</b> <i>и на эту строку нет ответа</i>
<b>hello??</b> <i>и на эту строку нет ответа</i>
<b>^D</b> <i>наш символ конца файла</i>
hello, world <i>затем выводятся три отраженные строки</i>
and hi
hello??
Здесь возникает проблема буферизации, поскольку сервер ничего не отражает, пока мы не введем наш символ конца файла. Выполняются следующие шаги:
■ Мы набираем первую строку ввода, и она отправляется серверу.
■ Сервер читает строку с помощью функции
fgets
fputs
■ Но стандартный поток ввода-вывода сервера полностью буферизован стандартной библиотекой ввода-вывода. Это значит, что библиотека копирует отраженную строку в свой стандартный буфер ввода-вывода для этого потока, но не выдает содержимое буфера в дескриптор, поскольку буфер не заполнен.
■ Мы набираем вторую строку ввода, и она отправляется серверу.
■ Сервер читает строку с помощью функции
fgets
fputs
■ Снова стандартная библиотека ввода-вывода сервера только копирует строку в свой буфер, но не выдает содержимое буфера в дескриптор, поскольку он не заполнен.
■ По тому же сценарию вводится третья строка.
■ Мы набираем наш символ конца файла, и функция
str_cli
shutdown
■ TCP сервера получает сегмент FIN, который читает функция
fgets
fgets
■ Функция
str_echo
main
exit
■ Библиотечная функция
exit
fputs
■ Дочерний процесс сервера завершается, в результате чего закрывается его присоединенный сокет, клиенту отсылается сегмент FIN и заканчивается последовательность завершения соединения TCP.
■ Наша функция
str_cli
■ Затем функция
str_cli
Проблема здесь заключается в том, что буферизация на стороне сервера выполняется автоматически стандартной библиотекой ввода-вывода. Существует три типа буферизации, выполняемой стандартной библиотекой ввода-вывода.