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

void sock_set_addr(const struct sockaddr *sockaddr,

 socklen_t addrlen, void *ptr);

void sock_set_port(const struct sockaddr *sockaddr,

 socklen_t addrlen, int port);

void sock_set_wild(struct sockaddr *sockaddr, socklen_t addrlen);

Функция 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, и в наших программах обычно вызываем именно обертки. Мы не приводим в данной книге исходный код для этих функций, так как он свободно доступен (см. предисловие).

<p>3.9. Функции readn, writen и readline</p>

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

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

#include "unp.h"

ssize_t readn(int filedes, void *buff, size_t nbytes);

ssize_t writen(int filedes, const void *buff, size_t nbytes);

ssize_t readline(int filedes, void *buff, size_t maxlen);

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

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

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

//lib/readn.c

 1 #include "unp.h"

 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 > 0) {

11   if ((nread = read(fd, ptr, nleft)) < 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); /* возвращает значение >= 0 */

22 }

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

//lib/writen.c

 1 #include "unp.h"

 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 > 0) {

11   if ((nwritten = write(fd, ptr, nleft)) <= 0) {

Перейти на страницу:

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

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

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги