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

Интервал:

Закладка:

Сделать

//names/daytimetcpcli.c

1 #include "unp.h"

2 int

3 main(int argc, char **argv)

4 {

5 int sockfd, n;

6 char recvline[MAXLINE + 1];

7 socklen_t len;

8 struct sockaddr_storage *ss;

9 if (argc != 3)

10 err_quit

11 ("usage, daytimetcpcli ");

12 sockfd = Tcp_connect(argv[1], argv[2]);

13 len = sizeof(ss);

14 Getpeername(sockfd, (SA*)&ss, &len);

15 printf("connected to %s\n", Sock_ntop_host((SA*)&ss, len));

16 while ((n = Read(sockfd, recvline, MAXLINE)) > 0) {

17 recvline[n] = 0; /* завершающий нуль */

18 Fputs(recvline, stdout);

19 }

20 exit(0);

21 }

Аргументы командной строки

9-11 Теперь нам требуется второй аргумент командной строки для задания либо имени службы, либо номера порта, что позволит нашей программе соединяться с другими портами.

Соединение с сервером

12 Теперь весь код сокета для этого клиента выполняется функцией tcp_connect.

Вывод ответа сервера

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

Обратите внимание, что функция tcp_connectне возвращает размера структуры адреса сокета, который использовался для функции connect. Мы могли добавить еще один аргумент-указатель, чтобы получить это значение, но при создании этой функции мы стремились добиться меньшего числа аргументов, чем у функции getaddrinfo. Поэтому мы определяем константу MAXSOCKADDRв нашем заголовке unp.hтак, чтобы ее размер равнялся размеру наибольшей структуры адреса сокета. Обычно это размер структуры адреса доменного сокета Unix (см. раздел 14.2), немного более 100 байт. Мы выделяем в памяти пространство для структуры указанного размера и заполняем ее с помощью функции getpeername.

Эта версия нашего клиента работает и с IPv4, и с IPv6, тогда как версия, представленная в листинге 1.1, работала только с IPv4, а версия из листинга 1.2 — только с IPv6. Сравните нашу новую версию с представленной в листинге Д.6, которую мы написали, чтобы использовать функции gethostbynameи getservbynameдля поддержки и IPv4, и IPv6.

Сначала мы задаем имя узла, поддерживающего только IPv4:

freebsd % daytimetcpcli linux daytime

connected to 206 168.112.96

Sun Jul 27 23:06:24 2003

Затем мы задаем имя узла, поддерживающего и IPv4, и IPv6:

freebsd % daytimetcpcli aix daytime

connected to 3ffe:b80:1f8d:2:204:acff:fe17:bf38

Sun Jul 27 23:17:13 2003

Используется адрес IPv6, поскольку у узла имеется и запись типа AAAA, и запись типа А. Кроме того, функция tcp_connectустанавливает семейство адресов AF_UNSPEC, поэтому, как было отмечено в табл. 11.3, сначала идет поиск записей типа AAAA, и только если этот поиск неудачен, выполняется поиск записей типа А.

В следующем примере мы указываем на необходимость использования именно адреса IPv4, задавая имя узла с суффиксом -4, что, как мы отмечали в разделе 11.2, в соответствии с принятым нами соглашением означает имя узла, который поддерживает только записи типа А:

freebsd % daytimetcpcli aix-4 daytime

connected to 192.168.42.2

Sun Jul 27 23:17:48 2003

11.13. Функция tcp_listen

Наша следующая функция, tcp_listen, выполняет обычные шаги сервера TCP: создание сокета TCP, связывание его с заранее известным портом с помощью функции bind и разрешение приема входящих запросов через соединение. В листинге 11.6 представлен исходный код.

#include "unp.h"

int tcp_listen(const char * hostname , const char * service , socklen_t * lenptr );

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

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

//lib/tcp_listen.c

1 #include "unp.h"

2 int

3 tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)

4 {

5 int listenfd, n;

6 const int on = 1;

7 struct addrinfo hints, *res, *ressave;

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

9 hints.ai_flags = AI_PASSIVE;

10 hints.ai_family = AF_UNSPEC;

11 hints.ai_socktype = SOCK_STREAM;

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

13 err_quit("tcp_listen error for %s, %s: %s",

14 host, serv, gai_strerror(n));

15 ressave = res;

16 do {

17 listenfd =

18 socket(res->ai_family, res->ai_socktype, res->ai_protocol);

19 if (listenfd < 0)

20 continue; /* ошибка, пробуем следующий адрес */

21 Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

22 if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0)

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

24 Close(listenfd); /* ошибка при вызове функции bind, закрываем

сокет и пробуем следующий адрес*/

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

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

вызове функции socket() или bind() */

27 err_sys("tcp_listen error for %s, %s", host, serv);

28 Listen(listenfd, LISTENQ);

29 if (addrlenp)

30 *addrlenp = res->ai_addrlen; /* возвращает размер адреса протокола */

31 freeaddrinfo(ressave);

32 return (listenfd);

33 }

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

8-15 Мы инициализируем структуру addrinfoс учетом следующих рекомендаций (элементов структуры hints): AI_PASSIVE, поскольку это функция для сервера, AF_UNSPECдля семейства адресов и SOCK_STREAM. Вспомните табл. 11.3: если имя узла не задано (что вполне нормально для сервера, который хочет связать с дескриптором универсальный адрес), то наличие значений AI_PASSIVEи AF_UNSPECвызовет возвращение двух структур адреса сокета: первой для IPv6 и второй для IPv4 (в предположении, что это узел с двойным стеком).

Создание сокета и связывание с адресом

16-24 Вызываются функции socketи bind. Если любой из вызовов окажется неудачным, мы просто игнорируем данную структуру addrinfoи переходим к следующей. Как было сказано в разделе 7.5, для сервера TCP мы всегда устанавливаем параметр сокета SO_REUSEADDR.

Проверка на наличие ошибки

25-26 Если все вызовы функций socketи bindокажутся неудачными, мы сообщаем об ошибке и завершаем выполнение. Как и в случае с нашей функцией tcp_connectиз предыдущего раздела, мы не пытаемся возвратить ошибку из этой функции.

27 Сокет превращается в прослушиваемый сокет с помощью функции listen.

Возвращение размера структуры адреса

28-31 Если аргумент addrlenpявляется непустым указателем, мы возвращаем размер адресов протокола через этот указатель. Это позволяет вызывающему процессу выделять память для структуры адреса сокета, чтобы получить адрес протокола клиента из функции accept (см. также упражнение 11.7).

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

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

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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