-->

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

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

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

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

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

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

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

//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 <hostname/IPaddress> <service/port#>");

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

13  len = sizeof(ss);

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

15  printf("connected to %sn", 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 % <b>daytimetcpcli linux daytime</b>

connected to 206 168.112.96

Sun Jul 27 23:06:24 2003

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

freebsd % <b>daytimetcpcli aix daytime</b>

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 % <b>daytimetcpcli aix-4 daytime</b>

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 &quot;unp.h&quot;

int tcp_listen(const char *<i>hostname</i>, const char *<i>service</i>, socklen_t *<i>lenptr</i>);

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

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

//lib/tcp_listen.c

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

 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(&amp;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, &amp;hints, &amp;res)) != 0)

13   err_quit(&quot;tcp_listen error for %s, %s: %s&quot;,

14    host, serv, gai_strerror(n));

Перейти на страницу:
Комментариев (0)
название