Это расширение является ЭКСПЕРИМЕНТАЛЬНЫМ. Поведение этого расширения, имена его функций и всё, что задокументировано, может измениться в последующих релизах РНР без предупреждения. Вы предупреждены и можете использовать это расширение только под вашу ответственность.
Расширение сокетов реализует низкоуровневый интерфейс
функций сообщений через сокеты на основе популярных BSD-сокетов, давая
возможность работать и как серверу сокетов, и как клиенту.
Функции сокетов, описанные здесь, являются частью расширения
PHP, которое обязано быть подключено на этапе компиляции с помощью опции --enable-sockets option
в configure.
При использовании этих функций важно помнить,
что, хотя многие из них имеют имена, аналогичные их двойникам языка C, они часто
имеют разные объявления. Обязательно прочтите описания, чтобы исключить конфликты.
Расширение сокетов было написано с целью предоставить интерфейс для мощных BSD-сокетов.
Особое внимание было обращено на то, чтобы эти функции хорошо работали в
реализациях как для Win32, так и Unix. Почти все функции сокетов могут потерпеть
неудачу при определённых условиях и, следовательно, выдать сообщение
E_WARNING с описанием ошибки. Иногда это не происходит по
желанию разработчика. Например, функция
socket_read() может выдать сообщение
E_WARNING, если соединение было внезапно разорвано. Обычно
предупреждения подавляются операцией @, а код ошибки отлавливается в
приложении функцией socket_last_error().
Вы можете вызвать функцию socket_strerror()
с кодом ошибки, чтобы получить строку с описанием этой ошибки. См. дополнительно описания функций.
Примечание: сообщения E_WARNING,
сгенерированные расширением сокетов, выводятся на английском, а получаемое
сообщение об ошибке будет зависеть от текущих локальных установок (LC_MESSAGES):
Warning! - socket_bind() unable to bind address [98]: Die Adresse wird bereits verwendet
Те, кто мало знаком с программированием сокетов, могут найти соответствующий
материал на Unix man-страницах; в web также имеется большое количество учебной
информации о программировании сокетов на C, большая часть которой может быть
применена, с некоторыми изменениями, для программирования сокетов в PHP. UNIX Socket FAQ
может стать хорошим началом.
Пример 1. Сокет: Простой TCP/IP-сервер
Это пример простого talkback-сервера. Измените переменные address и port
для ваших установок и запустите. Вы можете затем соединиться с сервером командой
вроде этой: telnet 192.168.1.53 10000 (где address и port соответствуют
вашим установкам). Всё, что вы напечатаете, будет затем выведено на стороне
сервера и возвращено вам обратно. Для отсоединения введите 'quit'.
#!/usr/local/bin/php -q
<?php
error_reporting (E_ALL);
/* Разрешить скрипту зависнуть в ожидании соединений. */
set_time_limit (0);
/* Включить неявную очистку вывода, и мы увидим всё получаемое
* по мере поступления. */
ob_implicit_flush ();
$address = '192.168.1.53';
$port = 10000;
if (($sock = socket_create (AF_INET, SOCK_STREAM, 0)) < 0) {
echo "socket_create() failed: reason: " . socket_strerror ($sock) . "\n";
}
if (($ret = socket_bind ($sock, $address, $port)) < 0) {
echo "socket_bind() failed: reason: " . socket_strerror ($ret) . "\n";
}
if (($ret = socket_listen ($sock, 5)) < 0) {
echo "socket_listen() failed: reason: " . socket_strerror ($ret) . "\n";
}
do {
if (($msgsock = socket_accept($sock)) < 0) {
echo "socket_accept() failed: reason: " . socket_strerror ($msgsock) . "\n";
break;
}
/* Отправить инструкции. */
$msg = "\nWelcome to the PHP Test Server. \n" .
"To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
socket_write($msgsock, $msg, strlen($msg));
do {
if (FALSE === ($buf = socket_read ($msgsock, 2048))) {
echo "socket_read() failed: reason: " . socket_strerror ($ret) . "\n";
break 2;
}
if (!$buf = trim ($buf)) {
continue;
}
if ($buf == 'quit') {
break;
}
if ($buf == 'shutdown') {
socket_close ($msgsock);
break 2;
}
$talkback = "PHP: You said '$buf'.\n";
socket_write ($msgsock, $talkback, strlen ($talkback));
echo "$buf\n";
} while (true);
socket_close ($msgsock);
} while (true);
socket_close ($sock);
?>
Пример 2. Сокет: простой TCP/IP-клиент
Это простой HTTP-клент. Он соединяет со страницей, отправляет HEAD-запрос,
возвращает ответ и выходит.
<?php
error_reporting (E_ALL);
echo "<h2>TCP/IP Connection</h2>\n";
/* Получить порт для WWW-сервиса. */
$service_port = getservbyname ('www', 'tcp');
/* Получить IP-адрес для целевого хоста. */
$address = gethostbyname ('www.example.com');
/* Создать TCP/IP-сокет. */
$socket = socket_create (AF_INET, SOCK_STREAM, 0);
if ($socket < 0) {
echo "socket_create() failed: reason: " . socket_strerror ($socket) . "\n";
} else {
echo "OK.\n";
}
echo "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect ($socket, $address, $service_port);
if ($result < 0) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
} else {
echo "OK.\n";
}
$in = "HEAD / HTTP/1.0\r\n\r\n";
$out = '';
echo "Sending HTTP HEAD request...";
socket_write ($socket, $in, strlen ($in));
echo "OK.\n";
echo "Reading response:\n\n";
while ($out = socket_read ($socket, 2048)) {
echo $out;
}
echo "Closing socket...";
socket_close ($socket);
echo "OK.\n\n";
?>