Функции сокетов
Расширение сокетов реализует низкоуровневый интерфейс
функций сообщений через сокеты на основе популярных BSD-сокетов, давая
возможность работать и как серверу сокетов, и как клиенту.
Эти функции всегда доступны.
Функции сокетов, описанные здесь - часть расширения PHP, которое нужно включить во времени компиляции PHP, c опцией --enable-sockets.
Замечание: Поддержка IPv6 была добавлена в PHP 5.0.0.
О более общем клиентском интерфейсе сокетов см.
fsockopen() и
pfsockopen().
При использовании этих функций важно помнить,
что, хотя многие из них имеют имена, аналогичные их двойникам языка 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, SOL_TCP)) < 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;
}
/* Send instructions. */
$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, PHP_NORMAL_READ))) {
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";
/* Get the port for the WWW service. */
$service_port = getservbyname('www', 'tcp');
/* Get the IP address for the target host. */
$address = gethostbyname('www.example.com');
/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
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.1\r\n";
$in .= "Host: www.example.com\r\n";
$in .= "Connection: Close\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";
?> |
|
- Содержание
- socket_accept - принимает
соединение на сокете
- socket_bind - связывает имя с
сокетом
- socket_clear_error - очищает
ошибку на сокете или последний код ошибки
- socket_close - закрывает ресурс
сокета
- socket_connect - инициирует
соединение с сокетом
- socket_create_listen -
открывает сокет на порте для приёма соединений
- socket_create_pair - создаёт
пару одинаковых сокетов и сохраняет их в fds
- socket_create - создаёт сокет (конечный пункт для соединения)
- socket_get_option - получает опции сокета
- socket_getpeername -
запрашивает удалённую сторону данного сокета, что может дать host/port, или путь файловой системы UNIX, в зависимости от типа
- socket_getsockname -
запрашивает локальную сторону данного сокета, что может дать host/port, или путь файловой системы UNIX, в зависимости от типа
- socket_last_error - возвращает последнюю ошибку на сокете
- socket_listen - прослушивает соединение на сокете
- socket_read - читает максимальное количество байт с сокета
- socket_recv - получает данные из соединённого сокета
- socket_recvfrom - получает данные из сокета, соединённого иди нет
- socket_select - запускает системный вызов select() на данных массивах сокетов с таймаутом, специфицированным tv_sec и tv_usec
- socket_send - отправляет данные в соединённый сокет
- socket_sendto - отправляет сообщение на сокет, независимо от того, соединён он или нет
- socket_set_nonblock - устанавливает неблокирующий режим для дескриптора файла fd
- socket_set_option - устанавливает опции сокета
- socket_shutdown - отключает приём, отправку с сокета, или и то, и другое
- socket_strerror - возвращает строку с описанием ошибки сокета
- socket_write - записывает в сокет
|