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

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

Шрифт:

Следующая функция,

start_connect
, показанная в листинге 16.11, инициирует вызов неблокируемой функции connect.

Листинг 16.11. Инициирование неблокируемой функции connect

//nonblock/start_connect.c

1 #include "web.h"

2 void

3 start_connect(struct file *fptr)

4 {

5 int fd, flags, n;

6 struct addrinfo *ai;

7 ai = Host_serv(fptr->f_host, SERV, 0, SOCK_STREAM);

8 fd = Socket(ai->ai_family; ai->ai_socktype, ai->ai_protocol);

9 fptr->f_fd = fd;

10 printf("start_connect for %s, fd %d\n", fptr->f_name, fd);

11 /* отключаем блокирование сокета */

12 flags = Fcntl(fd, F_GETFL, 0);

13 Fcntl(fd, F_SETFL, flags | O_NONBLOCK);

14 /* инициируем неблокируемое соединение с сервером */

15 if ((n = connected, ai->ai_addr, ai->ai_addrlen)) < 0) {

16 if (errno != EINPROGRESS)

17 err_sys("nonblocking connect error");

18 fptr->f_flags = F_CONNECTING;

19 FD_SET(fd, &rset); /* включаем дескриптор сокета в наборе чтения

и записи */

20 FD_SET(fd, &wset);

21 if (fd > maxfd)

22 maxfd = fd;

23 } else if (n >= 0) /* соединение уже установлено */

24 write_get_cmd(fptr); /* отправляем команду GET серверу */

25 }

Создание сокета, отключение блокировки сокета

7-13
Мы вызываем нашу функцию
host_serv
для поиска и преобразования имени узла и имени службы. Она возвращает указатель на массив структур
addrinfo
. Мы используем только первую структуру. Создается сокет TCP, и он становится неблокируемым.

Вызов неблокируемой функции connect

14-22
Вызывается неблокируемая функция
connect
, и флагу файла присваивается значение
F_CONNECTING
. Включается дескриптор сокета и в наборе чтения, и в наборе записи, поскольку функция
select
будет ожидать любого из этих условий как указания на то, что установление соединения завершилось. При необходимости мы также обновляем значение
maxfd
.

Обработка завершения установления соединения

23-24
Если функция
connect
успешно завершается, значит, соединение уже установлено, и функция
write_get_cmd
(она показана в следующем листинге) посылает команду серверу.

Мы делаем сокет неблокируемым для функции

connect
, но никогда не переустанавливаем его в блокируемый режим, заданный по умолчанию. Это нормально, поскольку мы записываем в сокет только небольшое количество данных (команда GET следующей функции) и считаем, что эти данные занимают значительно меньше места, чем имеется в буфере отправки сокета. Даже если из-за установленного флага отсутствия блокировки при вызове функции
write
происходит частичное копирование, наша функция
writen
обрабатывает эту ситуацию. Если оставить сокет неблокируемым, это не повлияет на последующее выполнение функций
read
, потому что мы всегда вызываем функцию
select
для определения того момента, когда сокет станет готов для чтения.

В листинге 16.12 показана функция

write_get_cmd
, посылающая серверу команду HTTP GET.

Листинг 16.12. Отправка команды HTTP GET серверу

//nonblock/write_get_cmd.c

1 #include "web.h"

2 void

3 write_get_cmd(struct file *fptr)

4 {

5 int n;

6 char line[MAXLINE];

  • Читать дальше
  • 1
  • ...
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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