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

Тут можно читать онлайн Уильям Стивенс - UNIX: разработка сетевых приложений - бесплатно ознакомительный отрывок. Жанр: comp-osnet, издательство Питер, год 2007. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    UNIX: разработка сетевых приложений
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2007
  • Город:
    Санкт-Петербург
  • ISBN:
    5-94723-991-4
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

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

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

UNIX: разработка сетевых приложений - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Уильям Стивенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

socket(AF_INET, SOCK_STREAM, 6)

address: 140.252.1.4:13

socket(AF_INET, SOCK_STREAM, 6)

address: 140.252.104.1:13

socket(AF_INET, SOCK_STREAM, 0)

address: 140.252.3.6.13

socket(AF_INET, SOCK_STREAM, 0)

address: 140.252.4.100.13

socket(AF_INET, SOCK_STREAM, 0)

address: 140.252.1.4.13

Затем мы задаем наш узел aix, у которого имеется и запись типа AAAA, и запись типа А, не указывая семейства адресов. Имя службы — ftp, которая предоставляется только TCP.

freebsd % testga -h aix -s ftp -t stream

socket(AF_NET6, SOCK_STREAM, 6)

address: [3ffe:b80:1f8d:2:204:acff:fe17:bf38]:21

socket(AF_INET, SOCK_STREAM, 6)

address: 192.168.42.2:21

Поскольку мы не задали семейство адресов и запустили этот пример на узле, который поддерживает и IPv4, и IPv6, возвращаются две структуры: одна для IPv6 и одна для IPv4.

Затем мы задаем флаг AI_PASSIVE(параметр ), не указываем ни семейства адресов, ни имени узла (подразумевая универсальный адрес), задаем номер порта 8888 и не указываем тип сокета.

freebsd % testga -р -s 8888 -t stream

socket(AF_INET6, SOCK_STREAM, 6)

address: [::]:8888

socket(AF_INET, SOCK_STREAM, 6)

address: 0.0.0.0:8888

Возвращаются две структуры. Поскольку мы запустили эту программу на узле, поддерживающем и IPv4, и IPv6, не задав семейства адресов, функция getaddrinfoвозвращает универсальный адрес IPv6 и универсальный адрес IPv4. Структура IPv6 возвращается перед структурой IPv4, поскольку, как мы увидим в главе 12, клиент или сервер IPv6 на узле с двойным стеком может взаимодействовать с собеседниками по IPv6 и по IPv4.

11.11. Функция host_serv

Наш первый интерфейс функции getaddrinfoне требует от вызывающего процесса размещать в памяти структуру рекомендаций и заполнять ее. Вместо этого аргументами нашей функции host_servбудут интересующие нас поля — семейство адресов и тип сокета.

#include "unp.h"

struct addrinfo *host_serv(const char * hostname , const char * service , int family , int socktype );

Возвращает: в случае успешного выполнения указатель на структуру addrinfo. NULL в случае ошибки

В листинге 11.3 показан исходный код этой функции.

Листинг 11.3. Функция host_serv

//lib/host_serv.c

1 #include "unp.h"

2 struct addrinfo*

3 host_serv(const char *host, const char *serv, int family, int socktype)

4 {

5 int n;

6 struct addrinfo hints, *res;

7 bzero(&hints, sizeof(struct addrinfo));

8 hints.ai_flags = AI_CANONNAME; /* всегда возвращает каноническое имя */

9 hints.ai_family = family; /* AF_UNSPEC, AF_INET, AF_INET6, ... */

10 hints.ai_socktype = socktype; /* 0, SOCK_STREAM, SOCK_DGRAM, ... */

11 if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)

12 return (NULL);

13 return (res); /* возвращает указатель на первый элемент в связном

списке */

14 }

7-13 Функция инициализирует структуру рекомендаций ( hints), вызывает функцию getaddrinfoи возвращает пустой указатель, если происходит ошибка.

Мы вызываем эту функцию в листинге 16.11, когда нам нужно использовать getaddrinfoдля получения информации об узле и о службе и при этом мы хотим установить соединение самостоятельно.

11.12. Функция tcp_connect

Теперь мы напишем две функции, использующие функцию getaddrinfoдля обработки большинства сценариев клиентов и серверов TCP, которые мы создаем. Первая из этих функций, tcp_connect, выполняет обычные шаги клиента: создание сокета TCP и соединение с сервером.

#include "unp.h"

int tcp_connect(const char * hostname , const char * service );

Возвращает: в случае успешного соединения - дескриптор присоединенного сокета, в случае ошибки не возвращается ничего

В листинге 11.4 показан исходный код.

Листинг 11.4. Функция tcp_connect: выполнение обычных шагов клиента

/ /lib/tcp_connect.c

1 #include "unp.h"

2 int

3 tcp_connect(const char *host, const char *serv)

4 {

5 int sockfd, n;

6 struct addrinfo hints, *res, *ressave;

7 bzero(&hints, sizeof(struct addrinfo));

8 hints.ai_family = AF_UNSPEC;

9 hints.ai_socktype = SOCK_STREAM;

10 if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)

11 err_quit("tcp_connect error for %s, %s: %s",

12 host, serv, gai_strerror(n));

13 ressave = res;

14 do {

15 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

16 if (sockfd < 0)

17 continue; /* игнорируем этот адрес */

18 if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)

19 break; /* успех */

20 Close(sockfd); /* игнорируем этот адрес */

21 } while ((res = res->ai_next) != NULL);

22 if (res == NULL) /* значение errno устанавливается при

последней попытке connect() */

23 err_sys("tcp_connect error for %s, %s", host, serv);

24 freeaddrinfo(ressave);

25 return (sockfd);

26 }

Вызов функции getaddrinfo

7-13 функция getaddrinfoвызывается один раз, когда мы задаем семейство адресов AF_UNSPECи тип сокета SOCK_STREAM.

Перебор всех структур addrinfo до успешного выполнения или до окончания списка

14-25 Затем пробуется каждый IP-адрес: вызываются функции socketи connect. Если выполнение функции socketнеудачно, это не фатальная ошибка, так как такое может случиться, если был возвращен адрес IPv6, а ядро узла не поддерживает IPv6. Если выполнение функции connectуспешно, выполняется функция breakдля выхода из цикла. В противном случае, после того как перепробованы все адреса, цикл также завершается. Функция freeaddrinfoосвобождает всю динамически выделенную память.

Эта функция (как и другие наши функции, предоставляющие более простой интерфейс для функции getaddrinfoв следующих разделах) завершается, если либо оказывается неудачным вызов функции getaddrinfo, либо вызов функции connectне выполняется успешно. Возвращение из нашей функции возможно лишь в случае успешного выполнения. Было бы сложно возвратить код ошибки (одну из констант EAI_ xxx ), не добавляя еще одного аргумента. Это значит, что наша функция-обертка тривиальна:

Tcp_connect(const char *host, const char *serv) {

return(tcp_connect(host, serv));

}

Тем не менее мы по-прежнему вызываем функцию-обертку вместо функции tcp_connectради сохранения единообразия в оставшейся части книги.

ПРИМЕЧАНИЕ

Проблема с возвращаемым значением заключается в том, что дескрипторы неотрицательные, но мы не знаем, положительны или отрицательны значения EAI_xxx. Если бы эти значения были положительными, мы могли бы возвратить равные им по абсолютной величине отрицательные значения, когда вызов функции getaddrinfo окажется неудачным. Но мы также должны возвратить некое другое отрицательное значение, чтобы указать, что все структуры были перепробованы безуспешно.

Пример: клиент времени и даты

В листинге 11.5 показан наш клиент времени и даты из листинга 1.1, переписанный с использованием функции tcp_connect.

Листинг 11.5. Клиент времени и даты, переписанный с использованием функции tcp_connect

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Уильям Стивенс читать все книги автора по порядку

Уильям Стивенс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


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


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x