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

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

Шрифт:

40 if (readable_v6 <= 0)

41 continue;

42 #endif

43 for (i = 0; i <= maxi; i++) { /* проверка всех клиентов */

44 if ( (sockfd = client[i].connfd) < 0)

45 continue;

46 if (FD_ISSET(sockfd, &rset))

47 if (readable_conn(i) <= 0)

48 break; /* готовых дескрипторов больше нет */

49 }

50 }

51 exit(0);

52 }

Проверка прослушиваемого доменного сокета Unix

32-34
Прослушиваемый доменный сокет Unix проверяется в первую очередь, и если он готов, запускается функция
readable_listen
. Переменная
nready
— количество дескрипторов, которое функция select возвращает как готовые к чтению — является глобальной. Каждая из наших функций
readablе_XXX
уменьшает ее значение на 1, и новое значение этой переменной является возвращаемым значением функции. Когда ее значение достигает нуля, это говорит о том, что все готовые к чтению дескрипторы обработаны, и поэтому функция
select
вызывается снова.

Проверка символьных сокетов ICMP

35-42
Проверяется символьный сокет ICMPv4, а затем символьный сокет ICMPv6.

Проверка присоединенных доменных сокетов Unix

43-49
Затем проверяется, готов ли для чтения какой-нибудь из присоединенных доменных сокетов Unix. Готовность для чтения какого-либо из таких сокетов обозначает, что клиент отослал дескриптор или завершился.

В листинге 28.26 приведена функция

readable_listen
, вызываемая, когда прослушиваемый сокет готов для чтения. Это указывает на новое клиентское соединение.

Листинг 28.26. Обработка нового соединения клиента

//icmpd/readablе_listen.c

1 #include "icmpd.h"

2 int

3 readable_listen(void)

4 {

5 int i, connfd;

6 socklen_t clilen;

7 clilen = sizeof(cliaddr);

8 connfd = Accept(listenfd, (SA*)&cliaddr, &clilen);

9 /* поиск первой свободной структуры в массиве client[] */

10 for (i = 0; i < FD_SETSIZE; i++)

11 if (client[i].connfd < 0) {

12 client[i].connfd = connfd; /* сохранение дескриптора */

13 break;

14 }

15 if (i == FD_SETSIZE) {

16 close(connfd); /* невозможно обработать новый клиент */

17 return(--nready); /* грубое закрытие нового соединения */

18 }

19 printf("new connection, i = %d, connfd = %d\n", i, connfd);

20 FD_SET(connfd, &allset); /* добавление нового дескриптора в набор */

21 if (connfd > maxfd)

22 maxfd = connfd; /* для select */

23 if (i > maxi)

24 maxi = i; /* максимальный индекс в массиве client[] */

25 return(--nready);

26 }

7-25
Принимается соединение и используется первый свободный элемент массива
client
. Код данной функции скопирован из начала кода, приведенного в листинге 6.4. Если свободных элементов в массиве нет, мы закрываем новое соединение и занимаемся обслуживанием уже имеющихся клиентов.

Когда присоединенный сокет готов для чтения, вызывается функция

readablе_conn
(листинг 28.27), а ее аргументом является индекс данного клиента в массиве client.

Листинг 28.27. Считывание данных и, возможно, дескриптора от клиента

//icmpd/readable_conn.c

1 #include "icmpd.h"

2 int

3 readable_conn(int I)

4 {

  • Читать дальше
  • 1
  • ...
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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