Книга: Разработка приложений в среде Linux. Второе издание

17.8.4. Поиск номеров портов

17.8.4. Поиск номеров портов

Новые функции getaddrinfo() и getnameinfo() предлагают простое выполнение преобразований имен служб в номера портов с одновременным определением имени хоста. В старых реализациях поиск имен служб проводился абсолютно независимо от поиска имен хостов. Доступ к именам служб можно получить через функцию getservbyname().

#include <netdb.h>
struct servent * getservbyname(const char * name,
 const char * protocol);

Первый параметр name представляет собой имя службы, о которой в приложении требуется информация. Параметр protocol указывает протокол для использования. База данных служб содержит информацию о других протоколах (особенно UDP); конкретное определение протокола позволяет функции игнорировать информацию по другим протоколам. Параметр protocol обычно является строкой "tcp", хотя могут использоваться и другие имена протоколов, например, "udp".

Функция getservbyname() возвращает указатель на структуру, которая содержит информацию о запрашиваемой службе. Информация может перезаписываться при последующем вызове getservbyname(), поэтому важные данные нужно сохранять в приложении. Функция getservbyname() возвращает следующую информацию:

#include <netdb.h>
struct servent {
 char * s_name;     /* имя службы */
 char ** s_aliases; /* псевдонимы службы */
 int s_port;        /* номер порта */
 char * s_proto;    /* протокол для использования */
}

Каждая служба может иметь несколько имен, ассоциированных с ней, но только один номер порта. Переменная s_name регистрирует каноническое имя службы, s_port содержит официальный номер порта данной службы (представленный в сетевом порядке байтов), s_proto представляет протокол для использования (например, "tcp"). Член s_aliases является массивом указателей псевдонимов службы (указатель NULL обозначает конец списка).

Если функция не выполняет свою работу, то она возвращает NULL и устанавливает h_errno. Ниже приведен пример программы, которая извлекает TCP-службу, указанную в командной строке, и выводит на экран каноническое имя, номер порта и все псевдонимы данной службы.

 1: /* services.с */
 2:
 3: #include <netdb.h>
 4: #include <netinet/in.h>
 5: #include <stdio.h>
 6:
 7: /* Отображает номер порта TCP и все псевдонимы службы,
 8:    указанной в командной строке */
 9:
10: /* services.с отыскивает номер порта для службы */
11: int main(int argc, const char ** argv) {
12:  struct servent * service;
13:  char ** ptr;
14:
15:  if (argc != 2) {
16:   fprintf(stderr, "поддерживается только одиночный аргументn");
17:   return 1;
18:  }
19:
20:  /* поиск службы в /etc/services, в случае неудачи
21:     передается ошибка */
22:  service = getservbyname(argv[1] , "tcp");
23:  if (!service) {
24:   herror("getservbyname failed");
25:   return 1;
26:  }
27:
28:  printf("служба: %sn", service->s_name);
29:  printf("tcp-порт: %dn", ntohs(service->s_port));
31:  /* отобразить все псевдонимы, которые имеет данная служба */
32:  if (*service->s_aliases) {
33:   printf("псевдонимы:");
34:   for (ptr = service->s_aliases; *ptr; ptr++)
35:    printf(" %s", *ptr);
36:   printf("n");
37:  }
38:
39:  return 0;
40: }

Ниже показан пример запуска программы. Обратите внимание на то, что она извлекает службы либо по каноническому имени, либо по псевдониму.

$ ./services http
служба: http
tcp-порт: 80
$ ./services source
служба: chargen
tcp-порт: 19
псевдонимы: ttytst source

Оглавление книги


Генерация: 1.212. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз