Читаем 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) {

12    if (errno == EINTR)

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

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

Основы программирования в Linux
Основы программирования в Linux

В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стан­дартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым. Для начинающих Linux-программистов

Нейл Мэтью , Ричард Стоунс , Татьяна Коротяева

ОС и Сети / Программирование / Книги по IT
1001 совет по обустройству компьютера
1001 совет по обустройству компьютера

В книге собраны и обобщены советы по решению различных проблем, которые рано или поздно возникают при эксплуатации как экономичных нетбуков, так и современных настольных моделей. Все приведенные рецепты опробованы на практике и разбиты по темам: аппаратные средства персональных компьютеров, компьютерные сети и подключение к Интернету, установка, настройка и ремонт ОС Windows, работа в Интернете, защита от вирусов. Рассмотрены не только готовые решения внезапно возникающих проблем, но и ответы на многие вопросы, которые возникают еще до покупки компьютера. Приведен необходимый минимум технических сведений, позволяющий принять осознанное решение.Компакт-диск прилагается только к печатному изданию книги.

Юрий Всеволодович Ревич

Программирование, программы, базы данных / Интернет / Компьютерное «железо» / ОС и Сети / Программное обеспечение / Книги по IT