PHP: Программирование сокетов

PHP: Программирование сокетов

Индекс материала
PHP: Программирование сокетов
Создание клиентских сокетов.
Создание серверных сокетов
Одновременная работа с несколькими сокетами
Все страницы

Сокеты представляют собой чрезвычайно удобную, но в то же время плохо понятую технологию взаимодействия между двумя процессами в сети. Эти процессы могут существовать на одной и той же машине, общаясь друг с другом через локальный сокет, предназначенный для взаимодействия между процессами, либо на разных машинах через Internet. Хотя тема сокетов очень обширна, в данной статье представлены основы, которые необходимы для использования расширений РНР, предназначенных для написания собственных серверов и клиентов сокетов.

Кстати!

Для использования сокетов РНР должен быть скомпилирован с опцией ./configure --enable-sockets или же потребуется загружать расширения поддержки сокетов динамически.

Имейте в виду, что примеры, приведённые далее в этой статье, разработаны для запуска непосредственно из окружения оболочки с использованием версии РНР командной строки. Хотя их можно запустить в Web-браузере, делать это не рекомендуется. В случае сценариев, которые создают серверы сокетов, их применение можно продемонстрировать с помощью любых программ, способных устанавливать сетевое соединение через сокеты, например, telnet (что, собственно, и рекомендуется).

Основы сокетов

Хотя существует множество типов сокетов, все функции сокетов основаны на одном и том же базовом принципе — получении данных программой В от программы А. Эти программы могут работать на одной и той же машине с применением межпроцессного взаимодействия (Interprocess Communication — IPC), либо на удаленных машинах (таких как Web-сервер и браузеры).

Сокеты могут быть надежными, выполняющими все необходимое для обеспечения передачи данных из точки А в точку В (TCP), либо ненадежными, когда данные передаются без гарантии доставки (UDP).

Сокеты также бывают "блокирующими" и "неблокирующими". Блокирующие сокеты заставляют ваше приложение ожидать до тех пор, пока данные станут доступны, в то время как неблокирующие сокеты этого не делают. Хотя, как будет показано далее, все сокеты двунаправлены, все же существует разница между сокетами клиента и сервера.

Мы с вами рассмотрим ТСР-сокеты Internet, поскольку они наиболее широко используются на сегодняшний день. Тем не менее, концепции и примеры кода, приведенные здесь, применимы к большинству операций с сокетами.

Создание нового сокета

Независимо от типа создаваемого сокета (клиентский или серверный), все они инициализируются одинаковым способом — с помощью функции socket_create(). Синтаксис этой функции выглядит следующим образом:

socket_create($domain, $type, $protocol);

    Праметры:

  1. $domain - тип создаваемого сокета и должен принимать одно из значений, перечисленных в таблице констант доменов для сокеткых соединений

  2. $type - тип взаимодействия, которое будет осуществляться через сокет; допустимые значения приведены в таблице констант типов сокетов

  3. $protocol - протокол, используемый данным сокетом. Этот параметр может быть любым допустимым номером протокола (см. функцию getprotobyname() ) или константой SOL_UDP или SOL_TCP для соединений TCP/UDP.

В результате выполнения эта функция либо возвращает ресурс, представляющий созданный сокет, либо булевское значение false в случае ошибки.

Функция socket_create() - это первый вызов при любом взаимодействии сокетов, который инициализирует ресурс сокета, используемый в последующих операциях. Итак, сокеты могут использоваться как локально - для IPC, так и удаленно — в стиле клиент/сервер. Контекст конкретного применения сокета называется его доменом. Доступные в РНР домены, передаваемые функции socket_create() в параметре $domain, задаются константами из таблицы:

Константы доменов для сокеткых соединений

Константа Описание
AF_INET Протокол Internet IPv4
AF_INET6 Протокол Internet IPv6
AF_UNIX Локальное межпроцессное взаимодействие

После того, как домен установлен, нужно определить ТИП подключения для создаваемого сокета. Эти типы перечислены в следующей таблице:

Константы типов сокетов

Константа Описание
SOCK_STREAM Последовательный надежный двунаправленный поток, основанный на подключении. Используется наиболее часто.
SOCK_DGRAM Ненадежный сокет, без подключения, передающий данные фиксиро ванной длины. Очень хорош для потоков данных, в которых надеж ность не критична.
SOCK_SEQPACKET Подобен потоковым сокетам за исключением того, что данные пере даются н принимаются в виде пакетов фиксированной длины.
SOCK_RAW Неформатированное сокетное подключение, удобное для выполне ния операций ICMP (Internet Control Message Protocol — протокол управляющих сообщений Internet), таких как trace, ping и так далее.
SOCK_RDM Надежный, по непоследовательный сокет, подобный SOCK DGRAM.

Как видите, существует множество опций при выборе типа создаваемых сокетов. Вообще большинство сокетных соединений устанавливается с помощью сокетов SОСК_STREAM или SOCK_DGRAM. Учитывая очевидную полноту SOCK_STREAM (большая часть Internet работает по этому типу сокетов через TCP), может быть не совсем понятно, зачем нужны сокеты типа SOCK_DGRAM (используемые с протоколом UDP).

В конце концов, почему вообще вам может понадобиться "ненадежный" способ передачи данных? Ответ становится очевидным, когда возникает необходимость в получении постоянного потока данных, который обрабатывается в реальном времени, от сервера к клиенту. Поскольку для приложений подобного типа потерянные пакеты несущественны (поскольку такие приложения имеют дело с данными, привязанными ко времени, которые быстро устаревают), нет необходимости в повторной отправке пакетов.

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

Мы будем испольэовать сокеты Internet IPv4 типа SOCK_STREAM, работающие через соединения SOL_TCP (TCP), После того, как ресурс сокета создан, он может быть уничтожен с помощью функции socket_close(), имеющей следующий синтаксис:

socket_close($socket);

Здесь $socket - это сокет, подлежащий уничтожению.

Ошибки сокетов

Как и другие технологии, сокеты восприимчивы к таким ошибкам, как сетевые сбои. Когда вы работаете с сокетами, каждая функция имеет возможность (обычно, возвращая булевское значение false) сообщать о том, что что-то идет не так. Когда такая ситуация случается, вы можете получить информацию об ошибке с помощью двух функций. Первая из них - socket_last_error():

socket_last_error($socket);

Где $socket - это сокет, информацию об ошибке которого необходимо извлечь. Как следует из имени функции, она используется для того, чтобы вернуть последнюю ошибку, произошедшую в данном сокете. Эта ошибка представлена в виде целого числа. Чтобы транслировать его в понятную человеку форму, в API-интерфейсе сокетов предусмотрена дополнительная функция socket_strerror():

socket_strerror($error_code);

Где $error_code - это значение, которое получено из функции socket_last_error(). Эта функция вернет строку, описывающую ошибку, возвращенную функцией socket_last_error().



Добавить комментарий


Защитный код
Обновить



Кто на сайте
Сейчас 95 гостей онлайн