(PHP 5, PHP 7, PHP 8)
stream_socket_client — Открывает соединение с интернет-сокетом или с доменным Unix-сокетом
$address,&$error_code = null ,&$error_message = null ,$timeout = null ,$flags = STREAM_CLIENT_CONNECT ,$context = null
Функция начинает соединение потока или датаграммы с удалённым сокетом, который указали
в параметре address. Тип создаваемого сокета
определяется по транспорту, который указали через стандартное форматирование URL-адреса:
transport://target. Для сокетов интернет-домена
(AF_INET) наподобие TCP и UDP часть target
параметра address должна состоять из
имени хоста или IP-адреса, за которым следует двоеточие и номер порта. Для доменных
сокетов Unix часть target должна указывать на
файл сокета в файловой системе.
Замечание:
По умолчанию поток будет открыт в блокирующем режиме. Можно переключить поток в неблокирующий режим функцией stream_set_blocking() .
addressАдрес удалённого сокета для соединения.
error_codeПри сбое соединения функция присвоит параметру номер системной ошибки.
error_messageПри сбое соединения функция присвоит параметру сообщение о системной ошибке.
timeout
Число секунд, в течение которых должно произойти время ожидания системного
вызова connect(). По умолчанию используется значение директивы
default_socket_timeout.
Замечание:
Этот параметр применяется, только если попытки асинхронного подключения не предпринимаются.
Замечание:
Чтобы указать время ожидания для чтения или записи данных через сокет, вызывают функцию stream_set_timeout() , поскольку параметр
timeoutприменяется только при создании соединения через сокет.
flags
Поле битовой маски, которое может принимать значение любой комбинации флагов соединения.
Пока набор флагов соединения ограничен следующими значениями:
STREAM_CLIENT_CONNECT (по умолчанию),
STREAM_CLIENT_ASYNC_CONNECT
и STREAM_CLIENT_PERSISTENT .
contextДопустимый ресурс контекста, который создали функцией stream_context_create() .
В случае успешного выполнения функция возвращает ресурс потока, который можно
использовать с другими файловыми функциями (например,
fgets() , fgetss() ,
fwrite() , fclose()
и feof() ); если возникла ошибка, функция возвращает false .
В случае неудачного вызова функция заполнит параметры error_code
и error_message системной ошибкой,
которая произошла при системном вызове
connect(). Если значение, которое вернулось в параметре
error_code, равно 0 и функция
вернула значение false , это означает, что ошибка
произошла до вызова connect(). Это произошло,
вероятно, из-за проблемы инициализации сокета. Примите во внимание,
что параметры error_code
и error_message каждый раз будут передаваться по ссылке.
| Версия | Описание |
|---|---|
| 8.0.0 |
Параметры timeout и context теперь принимают значение null.
|
Пример #1 Пример использования функции stream_socket_client()
<?php
$fp = stream_socket_client("tcp://www.example.com:80", $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n");
while (!feof($fp)) {
echo fgets($fp, 1024);
}
fclose($fp);
}
?>Пример #2 Пример UDP-соединения
Получения дня и времени от UDP-службы daytime (порт 13) на localhost.
<?php
$fp = stream_socket_client("udp://127.0.0.1:13", $errno, $errstr);
if (!$fp) {
echo "ОШИБКА: $errno - $errstr<br />\n";
} else {
fwrite($fp, "\n");
echo fread($fp, 26);
fclose($fp);
}
?>UDP-сокеты иногда открываются без ошибки, даже если удалённый хост недоступен. Ошибка станет заметной, только когда данные будут читать из сокета или писать данные в сокет. Причина этого в том, что UDP — протокол без соединения, что означает, что операционная система не пытается установить соединение с сокетом, пока ей в действительности не нужно отправить или получить данные.
Замечание:
Числовые IPv6-адреса наподобие
fe80::1берут в квадратные скобки. Например:tcp://[fe80::1]:80.
Замечание:
В зависимости от окружения Unix-домены или произвольное время ожидания соединения могут быть недоступны. Список доступных транспортов можно получить функцией stream_get_transports() . Смотрите список встроенных транспортов на странице Список транспортов для работы с сокетами.
For those wanting to use stream_socket_client() to connect to a local UNIX socket who can't find documentation on how to do it, here's a (rough) example:
<?php
$sock = stream_socket_client('unix:///full/path/to/my/socket.sock', $errno, $errstr);
fwrite($sock, 'SOME COMMAND'."\r\n");
echo fread($sock, 4096)."\n";
fclose($sock);
?>The remote_socket argument, in its end (well... after the port), can also contain a "/" followed by a unique identifier. This is especially useful if you want to create multiple persistent connections to the same transport://host:port combo.
Example:
<?php
$socket = stream_socket_client('tcp://mysql.example.com:3306/root', $errorno, $errorstr, $timeout, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT);
?>
Note that while (p)fsockopen() follows a similar scheme, it doesn't have this particular feature.<?php STREAM_CLIENT_ASYNC_CONNECT ?> opens a non-blocking socket (contradictory to the default blocking mode described in the manual page).
You will have to check for its status using <?php stream_select ?> followed by <?php socket_import_stream ?> and <?php socket_get_option($socket, SOL_SOCKET, SO_ERROR) ?>
You wouldn't normally do this, but when you do, you're more or less using glibc multisocket patterns.
Here's a minimal example:
<?php
// open a "server" on port 7238 in a separate terminal (don't open it if you want to see the error path)
// Netcat: nc -l 7238
// Socat: socat TCP-LISTEN:7238,fork,reuseaddr STDIO
$stream = stream_socket_client("tcp://127.0.0.1:7238", $errno, $errstr, flags: STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT);
while (true) {
$w = [$stream];
$r = $e = [];
$changed = stream_select($r, $w, $e, 1, 0);
// if $changed is false, there's an error that I'm not handling here
if (in_array($stream, $w)) {
break;
}
}
$socket = socket_import_stream($stream);
$so_error = socket_get_option($socket, SOL_SOCKET, SO_ERROR);
if ($so_error === 0) {
fwrite($stream, "Hello!\n");
} else {
// you'll have to look up the constant in <errno.h>
// for example, 111 is ECONNREFUSED
echo "There's been an error: errno=$so_error\n";
}
?>