Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Искомое имя хоста содержится в первом параметре и может равняться NULL
, если производится поиск только службы. Параметр hostname
может быть именем (например, www.ladweb.net
) или IP-адресом (с точками или двоеточиями в качестве разделителей), который функция getaddrinfo()
преобразует в двоичный адрес.
Второй параметр servicename
указывает имя той службы, для которой нужно извлечь официальный порт. Если он равен NULL
, то поиск службы не выполняется.
Структура struct addrinfo
используется как для hints
(при фильтрации полного списка адресов), так и для передачи окончательного списка в приложение.
#include
struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr_t * ai_addr;
char * ai_canonname;
struct addrinfo * next;
}
Если struct addrinfo
используется для параметра hints
, то участвуют только первые четыре члена, остальные должны равняться нулю или NULL
. Если задано значение ai_family
, то getaddrinfo()
возвращает адреса только для указанного семейства протоколов (например, PF_INET
). Аналогично, если устанавливается ai_socktype
, то возвращаются только адреса данного типа сокета.
Член ai_protocol
позволяет ограничивать результаты определенным протоколом. Этот параметр нельзя применять, если не установлен параметр ai_family
, а также, если числовое значение протокола (такое как IPPROTO_TCP
) не является уникальным среди всех протоколов; он хорошо подходит только для PF_INET
и PF_INET6
.
Последний член, используемый для hints
— это aflags
, который принимает одно или несколько (объединенных логическим "ИЛИ") из перечисленных ниже значений.
AI_ADDRCONFIG
По умолчанию функция getaddrinfo()
возвращает все адреса, соответствующие запросу. Данный флаг указывает на возврат адресов только тех протоколов, чьи адреса сконфигурированы в локальной системе. Другими словами, она возвращает только IPv4-адреса в системах с IPv4-интерфейсами и только IPv6-адреса в системах с интерфейсами IPv6.
AI_CANONNAME
При возврате поле ai_canonname
содержит каноническое имя хоста для адреса, указанного в struct addrinfo
. Поиск этого адреса сопровождается дополнительными поисками в службе DNS и, как правило, не является необходимым.
AI_NUMERICHOST
Параметр hostname
должен представлять собой адрес в форме с разделительными запятыми или двоеточиями. Никакие преобразования имени хоста не выполняются. Это предохраняет getaddrinfo()
от каких-либо поисков имени хоста, которые могут оказаться весьма длительным процессом.
AI_PASSIVE
Если hostname равен NULL
и присутствует этот флаг, то возвращается неустановленный адрес, который позволяет ожидать соединений на всех интерфейсах. Если данный флаг не указан (а значение hostname
равно NULL
), возвращается адрес обратной связи [135] Адрес обратной связи — это специальный адрес, который позволяет программам взаимодействовать через TCP/IP с приложениями только на одной и той же машине.
.
Последний параметр res
в getaddrinfo()
должен быть адресом указателя на struct addrinfo
. Для успешного завершения переменная, на которую указывает res
, устанавливается на первую запись в односвязном списке адресов, который соответствует запросу. Член ai_next
структуры struct addrinfo
указывает на следующий член связного списка, и для последнего узла в списке параметр ai_next
равен NULL
.
Когда приложение завершает работу с возвращенным связным списком, функция freeaddrinfo()
освобождает память, занимаемую списком.
#include
#include
#include
void freeaddrinfo(struct addrinfo * res);
Единственным параметром для freeaddrinfo
является указатель на первый узел в списке.
Каждый узел в возвращаемом списке имеет тип struct addrinfo
и специфицирует один адрес, соответствующий запросу. Каждый адрес содержит не только IPv4- или IPv6-адрес, он также определяет тип соединения (например, дейтаграмма) и протокол (такой как UDP). Если для одного IP-адреса в запросе подходит несколько типов соединений, то данный адрес включается в несколько узлов.
Каждый узел содержит описанную ниже информацию.
• ai_family
— семейство протоколов ( PF_INET
или PF_INET6
), к которому принадлежит адрес.
• ai_socktype
— тип соединения для адреса (как правило, принимает одно из значений SOCK_STREAM
, SOCK_DGRAM
или SOCK_RAW
).
• ai_protocol
— протокол для адреса (обычно IPPROTO_TCP
или IPPROTO_UDP
).
• Если в параметре hints
был указан флаг AI_CANONNAME
, то ai_canonname
содержит каноническое имя для адреса.
• ai_addr
указывает на struct sockaddr
для соответствующего протокола. Например, если ai_family
принимает значение PF_INET
, то ai_addr
указывает на struct sockaddr_in
. Член ai_addrlen
определяет длину структуры, на которую указывает ai_addr
.
• Если предусмотрен параметр servicename
, то в качестве номера порта в каждом адресе устанавливается официальный порт данной службы. В противном случае номер порта для каждого адреса равен нулю.
• Если не был передан параметр hostname
, то номера портов устанавливаются для каждого адреса, однако в качестве IP-адреса определяется или адрес обратной связи, или неустановленный адрес (как указывалось ранее в описании флага AI_PASSIVE
).
Все это может показаться достаточно запутанным. На самом деле, существует только два различных способа стандартного применения функции getaddrinfo()
. Большинство клиентских программ стремятся превратить имя хоста, передаваемое пользователем, и имя службы, известное программе, в полностью определенный адрес, с которым пользователь может установить соединение. Достичь этой цели нетрудно. Ниже приводится программа, которая принимает имя хоста как первый аргумент и имя службы как второй, после чего выполняет все необходимые преобразования.
1: /* clientlookup.c */
2:
3: #include
4: #include
5: #include
6:
7: int main(int argc, const char ** argv) {
8: struct addrinfo hints, * addr;
9: const char * host = argv[1], * service = argv[2];
10: int rc;
11:
12: if (argc != 3) {
13: fprintf(stderr, "требуется в точности два аргумента\n");
14: return 1;
15: }
16:
17: memset(&hints, 0, sizeof(hints));
18:
19: hints.ai_socktype = SOCK_STREAM;
20: hints.ai_flags = AI_ADDRCONFIG;
21: if ((rc = getaddrinfo(host, service, &hints, &addr)))
22: fprintf(stderr, "сбой поиска\n");
23: else
24: freeaddrinfo(addr);
25:
26: return 0;
27: }
Давайте обратим внимание на строки 17–24 этой программы. После очистки структуры hints приложение запрашивает адреса SOCK_STREAM
, которые используют протокол, сконфигурированный на локальной системе (путем установки флага AI_ADDRCONFIG
). Затем активизируется функция getaddrinfo()
с именем хоста, именем службы, подсказками и в случае невозможности найти соответствие отображается сообщение об ошибке. Если все проходит нормально, то первый элемент в связном списке, на который указывает addr
, представляет собой соответствующий адрес, который программа может использовать для установки соединения с указанной службой и хостом. Программа не решает, через какой протокол (IPv4 или IPv6) соединение будет лучшим.
Интервал:
Закладка: