W3docs

Функция PHP getprotobynumber(): всё, что нужно знать

Узнайте, как использовать функцию PHP getprotobynumber() для получения имени протокола по его номеру с примерами.

Сетевые протоколы передаются по сети в виде чисел, а не имён. В IP-пакете TCP — это 6, UDP — 17, ICMP — 1, и никаких человекочитаемых меток к ним не прилагается. Когда PHP-код считывает необработанный номер протокола (например, из разобранного пакета, журнала брандмауэра или вызова сети на уровне C), нередко требуется преобразовать это число обратно в понятное имя. Именно это делает функция getprotobynumber(): она находит номер протокола и возвращает его зарегистрированное имя.

В этой главе объясняется, что возвращает функция, как она читает системную базу данных протоколов, о чём следует помнить при переносимости кода и как она сочетается со своей обратной функцией getprotobyname().

Что такое функция getprotobynumber()?

getprotobynumber() — это встроенная функция PHP, которая сопоставляет числовой идентификатор протокола с его зарегистрированным именем. Она читает системную базу данных протоколов — как правило, /etc/protocols в Unix-подобных системах или %SystemRoot%\system32\drivers\etc\protocol в Windows — и возвращает соответствующее имя в виде string.

Распространённое заблуждение состоит в том, что функция возвращает array. Это не так: возвращаемое значение — обычная строка, например "tcp", или false, если протокол с таким номером не зарегистрирован в системе. Поскольку результат поиска зависит от локального файла протоколов, один и тот же номер теоретически может разрешаться по-разному в разных операционных системах, хотя широко известные номера протоколов стандартизированы IANA и одинаковы везде.

Синтаксис

getprotobynumber(int $protocol): string|false

Функция принимает один параметр:

  • $protocol: номер протокола для поиска (например, 6 для TCP).

При успешном поиске возвращает имя протокола в виде string; если номер не найден в базе данных протоколов — возвращает false.

Базовый пример

Номер протокола 6 соответствует TCP. В примере ниже выполняется поиск этого протокола, и случай неудачи обрабатывается явно с помощью строгого сравнения (===), поскольку false — единственный сигнал об ошибке:

php— editable, runs on the server

Вывод:

Protocol number 6 is 'tcp'

Используйте строгое сравнение === вместо !$protocol_name, так как корректное имя всегда является непустой строкой — но явная проверка на false делает намерение понятным и позволяет избежать граничных случаев.

Распространённые номера протоколов

Приведённые ниже широко известные номера стандартизированы IANA и присутствуют практически в каждой системе:

НомерИмяОписание
0ipInternet Protocol
1icmpInternet Control Message Protocol
2igmpInternet Group Management Protocol
6tcpTransmission Control Protocol
17udpUser Datagram Protocol
41ipv6Инкапсуляция IPv6
47greGeneric Routing Encapsulation
58ipv6-icmpICMP для IPv6

Можно перебрать диапазон номеров, чтобы увидеть, какие из них распознаёт ваша система:

<?php

foreach ([1, 6, 17, 132, 9999] as $number) {
  $name = getprotobynumber($number);
  echo $number . ' => ' . ($name === false ? '(unknown)' : $name) . PHP_EOL;
}

Номер 9999 не назначен, поэтому поиск вернёт false и выведет (unknown).

getprotobynumber() vs getprotobyname()

Эти две функции являются точными обратными функциями друг друга:

  • getprotobynumber(6) возвращает string "tcp".
  • getprotobyname("tcp") возвращает целое число 6.

Используйте getprotobynumber(), когда у вас есть необработанное число (из пакета, журнала или вызова сокета) и нужно получить читаемое имя. Используйте getprotobyname(), когда у вас есть имя и нужно получить число — например, чтобы передать его как аргумент $protocol при открытии необработанного сокета.

Когда это может понадобиться?

  • Чтение захватов пакетов или журналов брандмауэра, в которых записывается числовое поле протокола IP-заголовка.
  • Отображение понятного вывода в инструментах сетевой диагностики или мониторинга.
  • Проверка того, что номер протокола известен вашей системе, прежде чем действовать на его основе.

Для работы с сетью на более высоком уровне вы чаще будете обращаться к вспомогательным функциям поиска хостов и сервисов: getservbyport() и getservbyname() сопоставляют порты с именами сервисов, а gethostbyname() разрешает имена хостов.

Заключение

getprotobynumber() преобразует числовой идентификатор протокола в его зарегистрированное имя, возвращая string (не array) или false, если номер неизвестен. Она читает локальную базу данных протоколов и является обратной функцией getprotobyname(). Ключ к правильному использованию функции — понимание того, что она возвращает обычную строку, и проверка результата на false с помощью строгого сравнения.

Практика

Практика
Какая функция PHP используется для получения имени протокола по его номеру?
Какая функция PHP используется для получения имени протокола по его номеру?
Was this page helpful?