LINUX.ORG.RU

Книга «Linux API. Исчерпывающее руководство»

 , ,


5

2

Добрый день! Предлагаю вашему вниманию книгу «Linux API. Исчерпывающее руководство»(перевод книги The Linux Programming Interface). Ее можно заказать на сайте издательства, и если применить промокод LinuxAPI , то получите скидку 30%.

Отрывок из книги для ознакомления:

Сокеты: архитектура сервера

В этой главе мы обсудим основы проектирования итерационных и параллельных серверов, а также рассмотрим специальный демон inetd, который облегчает создание серверных интернет-приложений.

Итерационные и параллельные серверы

Существуют две распространенные архитектуры сетевых серверов на основе сокетов:

  • итерационная: сервер обслуживает клиентов по одному, сначала обрабатывая запрос (или несколько запросов) одного клиента и затем переходя к следующему;

  • параллельная: сервер спроектирован для обслуживания нескольких клиентов одновременно.

В разделе 44.8 уже был представлен пример итерационного сервера на основе очередей FIFO.

Итерационные серверы обычно подходят только в ситуациях, когда клиентские запросы можно обработать достаточно быстро, так как каждый клиент вынужден ждать, пока не обслужат любых других клиентов, находящихся перед ним. Обычным сценарием использования этого подхода является обмен единичными запросами и ответами между клиентом и сервером.

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

В следующих разделах мы рассмотрим примеры итерационного и параллельного серверов на основе сокетов интернет-домена. Эти два сервера реализуют упрощенный вариант службы echo (RFC 862), которая возвращает копию любого сообщения, посланного ей клиентом.

Итерационный UDP-сервер echo

В этом и следующем разделе мы представим серверы для службы echo. Она доступна на порте с номером 7 и работает как по UDP, так и по TCP (данный порт зарезервирован, в связи с чем сервер echo необходимо запускать с привилегиями администратора).

UDP-сервер echo постоянно считывает датаграммы и возвращает отправителю их копии. Поскольку серверу нужно обрабатывать только одно сообщение за раз, здесь будет достаточно итерационной архитектуры. Заголовочный файл для серверов показан в листинге 56.1.

Листинг 56.1. Заголовочный файл для программ id_echo_sv.c и id_echo_cl.c

#include "inet_sockets.h" /* Объявляет функции нашего сокета */
#include "tlpi_hdr.h"

#define SERVICE "echo" /* Имя UDP-службы */

#define BUF_SIZE 500 /* Максимальный размер датаграмм, которые
могут быть прочитаны клиентом и сервером */
____________________________________________________________________sockets/id_echo.h 

В листинге 56.2 представлена реализация сервера. Стоит отметить следующие моменты:

  • для перевода сервера в режим демона мы задействуем функцию becomeDaemon() из раздела 37.2;

  • чтобы сделать программу более компактной, мы используем библиотеку для работы с сокетами интернет-домена, разработанную в разделе 55.12;

  • если сервер не может вернуть ответ клиенту, то записывает сообщение в журнал, применяя вызов syslog().

В реальном приложении мы бы, скорее всего, ввели определенное ограничение на частоту записи сообщений с помощью syslog(). Это исключило бы возможность переполнения системного журнала злоумышленником. К тому же не стоит забывать, что каждый вызов syslog() довольно затратный, так как по умолчанию использует fsync().

Листинг 56.2. Итерационный сервер, который реализует UDP-службу echo

_________________________________________________________________sockets/id_echo_sv.c
#include <syslog.h>
#include "id_echo.h"
#include "become_daemon.h"

int
main(int argc, char *argv[])
{
   int sfd;
   ssize_t numRead;
   socklen_t len;
   struct sockaddr_storage claddr;
   char buf[BUF_SIZE];
   char addrStr[IS_ADDR_STR_LEN];

   if (becomeDaemon(0) == -1)
       errExit("becomeDaemon");

   sfd = inetBind(SERVICE, SOCK_DGRAM, NULL);
   if (sfd == -1) {
      syslog(LOG_ERR, "Could not create server socket (%s)",
         strerror(errno));
      exit(EXIT_FAILURE);

   /* Получаем датаграммы и возвращаем отправителям их копии */
   }
   for (;;) {
      len = sizeof(struct sockaddr_storage);
       numRead = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &claddr, &len);

       if (numRead == -1)
           errExit("recvfrom");
       if (sendto(sfd, buf, numRead, 0, (struct sockaddr *) &claddr, len)
            != numRead)
          syslog(LOG_WARNING, "Error echoing response to %s (%s)",
            inetAddressStr((struct sockaddr *) &claddr, len,
                addrStr, IS_ADDR_STR_LEN),
             strerror(errno));
   }
}
_________________________________________________________________sockets/id_echo_sv.c

Для проверки работы сервера мы используем программу из листинга 56.3. В ней тоже применяется библиотека для работы с сокетами интернет-домена, разработанная в разделе 55.12. В качестве первого аргумента командной строки клиентская программа принимает имя сетевого узла, на котором находится сервер. Клиент входит в цикл, где отправляет серверу каждый из оставшихся аргументов в виде отдельных датаграмм, а затем считывает и выводит датаграммы, полученные от сервера в ответ.

Листинг 56.3. Клиент для UDP-службы echo

#include "id_echo.h"

int
main(int argc, char *argv[])
{
   int sfd, j;
   size_t len;
   ssize_t numRead;
   char buf[BUF_SIZE];

   if (argc < 2 || strcmp(argv[1], "--help") == 0)
      usageErr("%s host msg...\n", argv[0]);

   /* Формируем адрес сервера на основе первого аргумента командной строки */
   sfd = inetConnect(argv[1], SERVICE, SOCK_DGRAM);
   if (sfd == -1)
      fatal("Could not connect to server socket");

   /* Посылаем серверу остальные аргументы в виде отдельных датаграмм */
   for (j = 2; j < argc; j++) {
      len = strlen(argv[j]);
      if (write(sfd, argv[j], len) != len)
         fatal("partial/failed write");

      numRead = read(sfd, buf, BUF_SIZE);
      if (numRead == -1)
         errExit("read");
      printf("[%ld bytes] %.*s\n", (long) numRead, (int) numRead, buf);
   }
   exit(EXIT_SUCCESS);
}
_________________________________________________________________sockets/id_echo_cl.c

Ниже показан пример того, что мы увидим при запуске сервера и двух экземпляров клиента:

$ su              // Для привязки к зарезервированному порту нужны привилегии
Password:
# ./id_echo_sv    // Сервер переходит в фоновый режим
# exit            // Отказываемся от прав администратора
$ ./id_echo_cl localhost hello world  // Этот клиент отправляет две датаграммы
[5 bytes] hello                       // Клиент выводит ответ, полученный от сервера
[5 bytes] world
$ ./id_echo_cl localhost goodbye      // Этот клиент шлет одну датаграмму
[7 bytes] goodbye

Желаю приятного чтения)

>>> Можно купить на сайте издательства



Проверено: alpha ()

Ответ на: комментарий от anonymous

В K&R, C89/C90 их не было, в C99 их добавили как обязательную возможно, а в C11 их сделали необязательными, то есть фактически убрали. В C11 так же добавили макрос __STDC_NO_VLA__ как раз для того, чтобы проверить включено ли это, теперь уже, опциональное расширение или нет.

bbk123 ★★★★★ ()
Последнее исправление: bbk123 (всего исправлений: 1)
Ответ на: комментарий от fsb4000

Но массивы в С есть и были всегда.

Это такие штоли:

int a[256], i;
for (i = sizeof(a)/sizeof(0[a]); --i <= 0; )
{
    i[a] = -i;
}
printf("%d\n",127[a]);
anonymous ()
Ответ на: комментарий от anonymous

Реализованы на уровне препроцессора на уровне синтаксического сахара и арифметики указателей. Об этом ещё K&R написали. По твоему это делает их не массивами, а чем-то другим? Расскажи чем.

bbk123 ★★★★★ ()
Ответ на: комментарий от bbk123

Расскажи чем

Сам же написал: синтаксическим сахаром над арифметикой указателей.

Что приведённый выше пример и демонстрирует.

anonymous ()
Ответ на: комментарий от anonymous

sizeof(0[a])

Наркоман штоле?

–i <= 0

Да, точно.

anonymous ()
Ответ на: комментарий от x-signal

ну стивенс ж чисто про сеть писал… а тут не только сеть… прям усё

xperious ★★ ()

2790… Пздц какой-то :(

Ладно. Весной куплю. Однако, бл@дь, дорого!

// Идите в электронный лес со своими электронными версиями.

anonymous ()

Вопрос: Это можно писать новости про все книжки из мира линукса или только именно эту ?

mx__ ★★★★★ ()

Книжка разумеется архивредная. Вместо изучения лучших практик мирового софтостроения на примере boost.asio, тысячи русскоговорящих макак начнут писать код сервера в стиле этой книжки.

И никто этим бедолагам не расскажет, что сервер на буст написать проше, а работать он будет быстрее и надежнее.

                                   Лиза.
anonymous ()
Ответ на: комментарий от anonymous

Ну, «Кому и кобыла невеста»…

… а кабан - тесть.

anonymous ()
Ответ на: комментарий от anonymous

Макаки не читают книг. Они, посмотрев пару видео, как раз будут пытаться применить то что с их точки зрения проще - boost итд., но так как они макаки и все делают стандартным обезьяньим методом, то и это тоже будет как обычно - криво, глюкаво, медленно.

anonymous ()
Ответ на: комментарий от anonymous

Ну успехов в изучении создания серверных приложений с помощью inetd. Автор - типичный инфоцыган.

                                Лиза.
anonymous ()

А откуда отрывок? Хочу увидеть пример TCP приема-отправки с сопроводительными комментариями, что бы судить о минимальной проф. пригодности автора.

zendrz ()
Ответ на: комментарий от anonymous

Я тебе больше скажу, часто для решения задачи требуется лишь написать модуль для nginx, а не теребить boost:asio понапрасну

zendrz ()
Ответ на: комментарий от zendrz

что бы судить о минимальной проф. пригодности автора.

Спешите видеть – некий zendrz с сайта linux.org.ru собрался судить о профпригодности Майкла Керриска.

anonymous ()
Ответ на: комментарий от anonymous

Вот именно, хотелось бы понять, не очередной ли это «Герберт Шилдт» или «Подбельский» с тысячей страниц вредных советов.

zendrz ()
Ответ на: комментарий от zendrz

А что тут понимать? Книжка - компиляция манов 20 летней давности.

                                        Лиза.
anonymous ()
Ответ на: комментарий от anonymous

since 2004, maintainer of the Linux man-pages project

Ну а что я говорила? Это же типичный тех. пейсатель, который в разработке не шарит ни хрена.

              Лиза.
anonymous ()

Пока её писали она устарела, пока её переводили ещё устарела. Как-то так с книгами в современном мире. А тут как?

ChekPuk ★★★ ()
Ответ на: комментарий от zendrz

Вот именно

Ты так ничего и не понял, хоть глянь, кто такой этот Керриск. Или ты и man’ы не читаешь, бегая с лупой, выискивая в них признаки «профнепригодности» в жалкой попытке потеребить собственное самолюбие?

anonymous ()
Ответ на: комментарий от ChekPuk

ЧекПук, повторю самого себя из этого треда – у тебя в 2021 какие-то кардинально новые open и pread? Или ты так, просто теоретик?

anonymous ()
Ответ на: комментарий от ChekPuk

Что там может устареть, дядя? Интерфейс libc не менялся лет 30 наверно.

     Лиза.
anonymous ()
Ответ на: комментарий от anonymous

Ну а что я говорила? Это же типичный тех. пейсатель, который в разработке не шарит ни хрена.

         Лиза.

Я не люблю аргумент «сперва добейся», может ты и вправду крутой/крутая/крутое разработчик/разработчица/разработчицо, но вот у нас есть весы – на одной чаше автор монументальной книги, а на другой – Лиза. Пока автор перевешивает с большим отрывом, просто потому, что Лиза известна только своими банами на каком-то сайте, но все еще может измениться. Лиза, твой выход.

          Майкл.
anonymous ()
Ответ на: комментарий от fsb4000

Спасибо. Посмотрел

Сойдет, минимальный тест на адекватность пройден. Правда, главную особенность практического использования сокетов засунуть в «Глава 57. Сокеты: углубленный материал, страница 1108» - это видимо для тех, кому какие-нибудь дроби в школе не давались :) Ну книга не чисто по сетям, поэтому и сойдет.

Но if (write(fd, buf, BUFLEN) != BUFLEN) { fatal( "Partial/failed write" ); } поначалу развеселил.

zendrz ()
Последнее исправление: zendrz (всего исправлений: 1)
Ответ на: комментарий от anonymous

Невзирая на авторитеты (я пока не знаю кто такой Керриск), я бы хотел убедиться, что там нет глупых, но частых, ошибок. Я убедился. Вместо поиска молитвы в честь биографии автора, я просто посмотрел текст книги и оценил то, что считал необходимым.

zendrz ()
Ответ на: комментарий от alpha

на таком уровне детализации, что там даётся, устаревает материал достаточно быстро.

В ленсуке user API не меняют. Что значит «устаревает»?

anonymous ()
Ответ на: комментарий от anonymous

Ты имеешь ввиду «компиляция 20 летней давности» или «маны 20 летней давности»?

С учетом

Англоязычное издание этой книги вышло в конце 2010 года

выглядит как просто очередная нетленка, на которую подешевели авторские права для переводчиков, и была издана в 2020 на русском.

zendrz ()
Ответ на: комментарий от zendrz

я просто посмотрел текст книги и оценил то, что считал необходимым.

Что тебе мешало сразу посмотреть текст книги, а потом уже писать про «профнепригодность», Шильдта и прочее? Или ты ждал пока тебе все разжуют, и ссылочку даже дадут? А потом конечно ты «просто» посмотрел и «оценил». Сообщи об этом автору тогда, чтоб он мог с гордостью говорить, что его книга «znedrz zdrnez zendrz approved».

             Майкл
anonymous ()
Ответ на: комментарий от anonymous

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

Лиза.

anonymous ()
Ответ на: комментарий от anonymous

Или ты ждал пока тебе все разжуют, и ссылочку даже дадут?

так дали же :)

Я просто придерживаюсь негласной политики ЛОРа - побольше болтовни и легкого троллинга для поддержания хоть какой-то активности сайта. Тем более в данном случае болтовня онтоп, да еще решилось все в позитивном ключе.

Так что все в порядке.Автор и мейнтейнер многих man-pages в линуксе выпустил книжку с этим материалом.

zendrz ()
Ответ на: комментарий от anonymous

не даю там мудацких советов

Да там вроде нет мудацких советов. Там обычный материал, как у Стивенса, например. Кто-то уже перерос, кому-то будет полезен. Вот ты с точки зрения опытного разработчика можешь вычитать и указать на неточности и ошибки, или заткнуться и пройти мимо.

zendrz ()
Ответ на: комментарий от zendrz

негласной политики ЛОРа - побольше болтовни и легкого троллинга

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

           Майкл
anonymous ()
Ответ на: комментарий от anonymous

Нет никакой всеобщей негласной политики поведения, у каждого она своя

А я думаю что есть. Но это уже оффтоп, предлагаю обсудить там Модераторы ЛОРа подписывают NDA? . Или туда анонимусов не пускают? Тогда сорян

zendrz ()
Последнее исправление: zendrz (всего исправлений: 2)
Ответ на: комментарий от anonymous

Но в отличие от автора не пишу книжки с претензией на фундаментальность

А жаль, с удовольствием полистал бы книгу от автора, которая «написала на плюсах неблокирующий rest сервер, который работает на линуксе, виндовс, фрибсд, солярисе и легко обрабатыет 15к коннектов», если же она конечно и вправду «написала на плюсах неблокирующий rest сервер, который работает на линуксе, виндовс, фрибсд, солярисе и легко обрабатыет 15к коннектов».

не даю там мудацких советов

Да ты всего лишь пишешь мудацкие посты на форуме.

             Майкл
anonymous ()
Ответ на: комментарий от alpha

Надо было сразу ссылку на торрент давать. Один Линус, это никто в здравом уме покупать не будет.

anonymous ()
Ответ на: комментарий от zendrz

нет мудацких советов

«В реальном приложении мы бы, скорее всего, ввели определенное ограничение на частоту записи сообщений с помощью syslog(). Это исключило бы возможность переполнения системного журнала злоумышленником. К тому же не стоит забывать, что каждый вызов syslog() довольно затратный, так как по умолчанию использует fsync().»

Читаем ман 5 syslog.conf

         Лиза.
anonymous ()

Кто-то решил филиал издательства «Питер» открыть на лоре…

ComradeDOS ()
Ответ на: комментарий от alpha

И, кстати сказать, Леннарт рекомендует.

«Леннарт рекомендует» — это как «Проверено Shaman007».

anonymous ()
Ответ на: Re: Вот эта книга? от anonymous

Re: Вот эта книга?

Следующий перевод будет под DRM

Вот это правильно, нечего ворью потакать.

anonymous ()
Ответ на: Re: Вот эта книга? от anonymous

Re: Вот эта книга?

… нечего ворью потакать.

и воровкам

anonymous ()
Ответ на: Re: Вот эта книга? от anonymous

Re: Вот эта книга?

и воровкам

На Лизу намекаешь? Так она и не ворует, просто берет в лизинг.

anonymous ()
Ответ на: Re: Вот эта книга? от anonymous

Re: Вот эта книга?

На Лизу намекаешь? Так она и не ворует, просто берет в лизинг.

Нет.
Просто «обобщил».

anonymous ()
Ответ на: Re: Вот эта книга? от anonymous

Re: Вот эта книга?

Нет. Просто «обобщил».

Знаю. Просто «пошутил».

anonymous ()
Ограничение на отправку комментариев: только для зарегистрированных пользователей