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

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

Шрифт:

Максимальное увеличение эффективности происходит при трех одновременных соединениях (время уменьшается вдвое), а при четырех и более одновременных соединениях прирост производительности значительно меньше.

16.6. Неблокируемая функция accept

Как было сказано в главе 6, функция

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

К сожалению, существует определенная проблема, связанная со временем, способная запутать нас [34]. Чтобы увидеть эту проблему, изменим код нашего эхо- клиента TCP (см. листинг 5.3) таким образом, чтобы после установления соединения серверу отсылался сегмент RST. В листинге 16.14 представлена новая версия.

Листинг 16.14. Эхо-клиент TCP, устанавливающий соединение и посылающий серверу сегмент RST

//nonblock/tcpcli03.c

1 #include "unp.h"

2 int

3 main(int argc, char **argv)

4 {

5 int sockfd;

6 struct linger ling;

7 struct sockaddr_in servaddr;

8 if (argc != 2)

9 err_quit("usage: tcpcli <IPaddress>");

10 sockfd = Socket(AF_INET, SOCK_STREAM, 0);

11 bzero(&servaddr, sizeof(servaddr));

12 servaddr.sin_family = AF_INET;

13 servaddr.sin_port = htons(SERV_PORT);

14 Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

15 Connect(sockfd, (SA*)&servaddr, sizeof(servaddr));

16 ling.l_onoff = 1; /* для отправки сегмента RST при закрытии соединения */

17 ling.l_linger = 0;

18 Setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));

19 Close(sockfd);

20 exit(0);

21 }

Установка параметра сокета SO_LINGER

16-19
Как только соединение устанавливается, мы задаем параметр сокета
SO_LINGER
, устанавливая флаг
l_onoff
в единицу и обнуляя время
l_linger
. Как утверждалось в разделе 7.5, это вызывает отправку RST на сокете TCP при закрытии соединения. Затем с помощью функции
close
мы закрываем сокет.

Потом мы изменяем наш сервер TCP, приведенный в листингах 6.3 и 6.4, с тем чтобы после сообщения функции

select
о готовности прослушиваемого сокета для чтения, но перед вызовом функции
accept
наступала пауза. В следующем коде, взятом из начала листинга 6.4, две добавленные строки помечены знаком
+
.

if (FD_ISSET(listenfd, &rset)) { /* новое соединение */

+ printf("listening socket readable\n");

+ sleep(5);

clilen = sizeof(cliaddr);

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

Здесь мы имитируем занятый сервер, который не может вызвать функцию

accept
сразу же, как только функция
select
сообщит, что прослушиваемый сокет готов для чтения. Обычно подобное замедление со стороны сервера не вызывает проблем (на самом деле именно для этих ситуаций предусмотрена очередь полностью установленных соединений). Но поскольку после установления соединения от клиента прибыл сегмент RST, у нас возникает проблема.

В разделе 5.11 мы отмечали, что когда клиент разрывает соединение до того, как сервер вызывает функцию

accept
, в Беркли-реализациях прерванное соединение не возвращается серверу, в то время как другие реализации должны возвращать ошибку
ECONNABORTED
, но часто вместо нее возвращают ошибку
EPROTO
. Рассмотрим Беркли-реализацию.

Клиент устанавливает соединение и затем прерывает его, как показано в листинге 16.14.

Функция

select
сообщает процессу сервера, что дескриптор готов для чтения, но у сервера вызов функции
accept
занимает некоторое, хотя и непродолжительное, время.

  • Читать дальше
  • 1
  • ...
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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