Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

Сокеты TCP и UDP являются двусторонними. Стандартные потоки ввода- вывода также могут быть двусторонними: мы просто открываем поток типа

r+
, что означает чтение-запись. Но в таком потоке за функцией вывода не может следовать функция ввода, если между ними нет вызова функции
fflush
,
fseek
,
fsetpots
или
rewind
. Аналогично, за функцией вывода не может следовать функция ввода, если между ними нет вызова функции
fseek
,
fsetpots
,
rewind
, в том случае, когда при вводе не получен признак конца файла. Проблема с последними тремя функциями состоит в том, что все они вызывают функцию
lseek
, которая не работает с сокетами.

Простейший способ обработки подобной проблемы чтения-записи — это открытие двух стандартных потоков ввода-вывода для данного сокета: одного для чтения и другого для записи.

Пример: функция str_echo, использующая стандартный ввод-вывод

Сейчас мы модифицируем наш эхо-сервер TCP (см. листинг 5.2) для использования стандартного ввода-вывода вместо функций

readline
и
writen
. В листинге 14.6 представлена версия нашей функции
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 % tcpcli02 206.168.112.96

hello, world мы набираем эту строку, но не получаем отражения

and hi и на эту строку нет ответа

hello?? и на эту строку нет ответа

^D наш символ конца файла

hello, world затем выводятся три отраженные строки

and hi

hello??

Здесь возникает проблема буферизации, поскольку сервер ничего не отражает, пока мы не введем наш символ конца файла. Выполняются следующие шаги:

Мы набираем первую строку ввода, и она отправляется серверу.

Сервер читает строку с помощью функции

fgets
и отражает ее с помощью функции
fputs
.

Но стандартный поток ввода-вывода сервера полностью буферизованстандартной библиотекой ввода-вывода. Это значит, что библиотека копирует отраженную строку в свой стандартный буфер ввода-вывода для этого потока, но не выдает содержимое буфера в дескриптор, поскольку буфер не заполнен.

Мы набираем вторую строку ввода, и она отправляется серверу.

Сервер читает строку с помощью функции

fgets
и отражает ее с помощью функции
fputs
.

Снова стандартная библиотека ввода-вывода сервера только копирует строку в свой буфер, но не выдает содержимое буфера в дескриптор, поскольку он не заполнен.

По тому же сценарию вводится третья строка.

Мы набираем наш символ конца файла, и функция

str_cli
(см. листинг 6.2) вызывает функцию
shutdown
, посылая серверу сегмент FIN.

  • Читать дальше
  • 1
  • ...
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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