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

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

Шрифт:

SHUT_RDWR
. Закрываются и читающая, и записывающая половины соединения. Это эквивалентно двум вызовам функции
shutdown
: сначала с аргументом
SHUT_RD
, затем — с аргументом
SHUT_WR
.

В табл. 7.4 приведены все возможные сценарии, доступные процессу при вызове функций

shutdown
и
close
. Действие функции close зависит от значения параметра сокета
SO_LINGER
.

ПРИМЕЧАНИЕ

Три константы SHUT_xxx определяются в спецификации POSIX. Типичные значения аргумента howto, с которыми вы встретитесь, — это 0 (закрытие читающей половины), 1 (закрытие записывающей половины) и 2 (закрытие обеих половин).

6.7. Функция str_cli (еще раз)

В листинге 6.2 представлена наша обновленная (и корректная) функция

str_cli
. В этой версии используются функции
select
и
shutdown
. Первая уведомляет нас о том, когда сервер закрывает свой конец соединения, а вторая позволяет корректно обрабатывать пакетный ввод. Эта версия избавлена от ориентации на строки. Вместо этого она работает с буферами, что позволяет полностью избавиться от проблем, описанных в конце раздела 6.5.

Листинг 6.2. функция str_cli, использующая функцию select, которая корректно обрабатывает конец файла

//select/strcliselect02.c

1 #include "unp.h"

2 void

3 str_cli(FILE *fp, int sockfd)

4 {

5 int maxfdp1, stdineof;

6 fd_set rset;

7 char buf[MAXLINE];

8 int n;

9 stdineof = 0;

10 FD_ZERO(&rset);

11 for (;;) {

12 if (stdineof == 0)

13 FD_SET(fileno(fp), &rset);

14 FD_SET(sockfd, &rset);

15 maxfdp1 = max(fileno(fp), sockfd) + 1;

16 Select(maxfdp1, &rset, NULL, NULL, NULL);

17 if (FD_ISSET(sockfd, &rset)) { /* сокет готов для чтения */

18 if ((n = Read(sockfd, buf, MAXLINE)) == 0) {

19 if (stdineof == 1)

20 return; /* нормальное завершение */

21 else

22 err_quit("str_cli: server terminated prematurely");

23 }

24 Write(fileno(stdout), buf, n);

25 }

26 if (FD_ISSET(fileno(fp), &rset)) { /* есть данные на входе */

27 if ((n = Read(fileno(fp), buf, MAXLINE)) == 0) {

28 stdineof = 1;

29 Shutdown(sockfd, SHUT_WR); /* отправка сегмента FIN */

30 FD_CLR(fileno(fp), &rset);

31 continue;

32 }

33 Writen(sockfd, buf, n);

34 }

35 }

36 }

5-8
stdineof
— это новый флаг, инициализируемый нулем. Пока этот флаг равен нулю, мы будем проверять готовность стандартного потока ввода к чтению с помощью функции
select
.

16-24
Если мы считываем на сокете признак конца файла, когда нам уже встретился ранее признак конца файла в стандартном потоке ввода, это является нормальным завершением и функция возвращает управление. Но если конец файла в стандартном потоке ввода еще не встречался, это означает, что процесс сервера завершился преждевременно. В новой версии мы вызываем функции
read
и
write
и работаем с буферами, а не со строками, благодаря чему функция
select
действует именно так, как мы рассчитывали.

  • Читать дальше
  • 1
  • ...
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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