-->

UNIX: разработка сетевых приложений

На нашем литературном портале можно бесплатно читать книгу UNIX: разработка сетевых приложений, Стивенс Уильям Ричард-- . Жанр: ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
UNIX: разработка сетевых приложений
Название: UNIX: разработка сетевых приложений
Дата добавления: 16 январь 2020
Количество просмотров: 378
Читать онлайн

UNIX: разработка сетевых приложений читать книгу онлайн

UNIX: разработка сетевых приложений - читать бесплатно онлайн , автор Стивенс Уильям Ричард

Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

1 ... 30 31 32 33 34 35 36 37 38 ... 399 ВПЕРЕД
Перейти на страницу:

void sock_set_wild(struct sockaddr *<i>sockaddr</i>, socklen_t <i>addrlen</i>);

Функция

sock_bind_wild
связывает универсальный адрес и динамически назначаемый порт с сокетом. Функция
sock_cmp_addr
сравнивает адресные части двух структур адреса сокета, а функция
sock_cmp_port
сравнивает номера их портов. Функция
sock_get_port
возвращает только номер порта, а функция
sock_ntop_host
преобразует к формату представления только ту часть структуры адреса сокета, которая относится к узлу (все, кроме порта, то есть IP-адрес узла). Функция
sock_set_addr
присваивает адресной части структуры значение, указанное аргументом
ptr
, а функция
sock_set_port
задает в структуре адреса сокета только номер порта. Функция
sock_set_wild
задает адресную часть структуры через символы подстановки. Как обычно, мы предоставляем для всех этих функций функции- обертки, которые возвращают значение, отличное от типа void, и в наших программах обычно вызываем именно обертки. Мы не приводим в данной книге исходный код для этих функций, так как он свободно доступен (см. предисловие).

3.9. Функции readn, writen и readline

Потоковые сокеты (например, сокеты TCP) демонстрируют с функциями

read
и
write
поведение, отличное от обычного ввода-вывода файлов. Функция
read
или
write
на потоковом сокете может ввести или вывести немного меньше байтов, чем запрашивалось, но это не будет ошибкой. Причиной может быть достижение границ буфера для сокета в ядре. Все, что требуется в этой ситуации — чтобы процесс повторил вызов функции
read
или
write
для ввода или вывода оставшихся байтов. (Некоторые версии Unix ведут себя аналогично при записи в канал (pipe) более 4096 байт.) Этот сценарий всегда возможен на потоковом сокете при выполнении функции
read
, но с функцией
write
он обычно наблюдается, только если сокет неблокируемый. Тем не менее вместо
write
мы всегда вызываем функцию
writen
на тот случай, если в данной реализации возможно возвращение меньшего количества данных, чем мы запрашиваем.

Введем три функции для чтения и записи в потоковый сокет.

#include &quot;unp.h&quot;

ssize_t readn(int <i>filedes</i>, void *<i>buff</i>, size_t <i>nbytes</i>);

ssize_t writen(int <i>filedes</i>, const void *<i>buff</i>, size_t <i>nbytes</i>);

ssize_t readline(int <i>filedes</i>, void *<i>buff</i>, size_t <i>maxlen</i>);

<i>Все функции возвращают: количество считанных или записанных байтов, -1 в случае ошибки</i>

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

readn
, в листинге 3.10 — функция
writen
, а в листинге 3.11 — функция
readline
.

Листинг 3.9. Функция readn: считывание n байт из дескриптора

//lib/readn.c

 1 #include &quot;unp.h&quot;

 2 ssize_t /* Считывает n байт из дескриптора */

 3 readn(int fd, void *vptr, size_t n)

 4 {

 5  size_t nleft;

 6  ssize_t nread;

 7  char *ptr;

 8  ptr = vptr;

 9  nleft = n;

10  while (nleft &gt; 0) {

11   if ((nread = read(fd, ptr, nleft)) &lt; 0) {

12    if (errno == EINTR)

13     nread = 0; /* и вызывает снова функцию read() */

14    else

15     return (-1);

16   } else if (nread == 0)

17   break; /* EOF */

18   nleft -= nread;

19   ptr += nread;

20  }

21  return (n - nleft); /* возвращает значение &gt;= 0 */

22 }

Листинг 3.10. Функция writen: запись n байт в дескриптор

//lib/writen.c

 1 #include &quot;unp.h&quot;

 2 ssize_t /* Записывает n байт в дескриптор */

 3 writen(int fd, const void *vptr, size_t n)

 4 {

 5  size_t nleft;

 6  ssize_t nwritten;

 7  const char *ptr;

 8  ptr = vptr;

 9  nleft = n;

10  while (nleft &gt; 0) {

11   if ((nwritten = write(fd, ptr, nleft)) &lt;= 0) {

12    if (errno == EINTR)

13     nwritten = 0; /* и снова вызывает функцию write() */

14    else

15     return (-1); /* ошибка */

16   }

17   nleft -= nwritten;

18   ptr += nwritten;

19  }

20  return (n);

21 }

Листинг 3.11. Функция readline: считывание следующей строки из дескриптора, по одному байту за один раз

//test/readline1.с

 1 #include &quot;unp.h&quot;

   /* Ужасно медленная версия, приводится только для примера */

 2 ssize_t

 3 readline(int fd, void *vptr, size_t maxlen)

1 ... 30 31 32 33 34 35 36 37 38 ... 399 ВПЕРЕД
Перейти на страницу:
Комментариев (0)
название