Получает данные из подключённого сокета

# socket_recv

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

socket_recv — Получает данные из подключённого сокета

### Описание

function socket_recv(
Socket `$socket`,
?string `&$data`,
int `$length`,
int `$flags`
): int|false

Функция socket_recv() получает из сокета `socket` данные длиной до заданного параметром `length` количества байтов, а затем заполняет данными буфер `data`. Функция socket_recv() умеет собирать данные из сокетов, с которыми установили соединение. Поведение функции изменяют флагами.

Параметр `data` — ссылка, поэтому значение в списке аргументов указывают как переменную. Функция socket_recv() вернёт данные, которые прочитает из сокета `socket`, в параметр `data`.

### Список параметров

`socket`

  Параметр `socket` принимает экземпляр класса Socket, который создали функцией socket_create().

`data`

  Функция извлечёт данные и заполнит ими параметр `data`. Функция установит для параметра `data` значение `null`, если возникла ошибка, сбросилось соединение или данные оказались недоступны.

`length`

  Параметр `length` определяет длину данных в байтах, до которой функция будет получать данные с удалённого хоста.

`flags`

  Параметр `flags` принимает произвольную комбинацию следующих флагов, которые соединили двоичным оператором ИЛИ — `|`.

  Значения флагов, которые принимает параметр `flags`
  Флаг | Описание
  --- | ---
  `MSG_OOB` | Обрабатывать внеполосные (out-of-band) данные.
  `MSG_PEEK` | Получать данные из начала очереди получения без удаления данных из очереди.
  `MSG_WAITALL` | Функция блокируется, пока не получит хотя бы `length` байтов. Однако в таких случаях, если сигнал перехватился или удалённый хост отключился, функция вернёт меньше данных.
  `MSG_DONTWAIT` | С этим флагом функция вернёт ответ, даже если обычно она бы заблокировалась.

### Возвращаемые значения

Функция socket_recv() возвращает количество байтов, которые получила, или `false`, если возникла ошибка. Код ошибки получают функцией socket_last_error(), а текстовое описание ошибки — функцией socket_strerror().

### Список изменений

Версия | Описание
--- | ---
8.0.0 | Параметр `socket` теперь принимает объект Socket; раньше принимался тип resource.

### Примеры

Пример #1 Пример получения данных из подключенного сокета функцией socket_recv()

Этот пример — просто переработка первого примера из статьи «Примеры», чтобы показать работу функции socket_recv().

    <?php

    error_reporting(E_ALL);

    echo "<h2>Соединение по протоколу TCP/IP</h2>\n";

    /* Получаем порт WWW-сервиса */
    $service_port = getservbyname('www', 'tcp');

    /* Получаем IP-адрес целевого хоста */
    $address = gethostbyname('www.example.com');

    /* Создаём сокет по протоколу TCP/IP. */
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    if ($socket === false) {
        echo "Не удалось выполнить функцию socket_create(): причина: " . socket_strerror(socket_last_error()) . "\n";
    } else {
        echo "OK.\n";
    }

    echo "Попытка соединиться с хостом '$address' на порте '$service_port'... ";
    $result = socket_connect($socket, $address, $service_port);
    if ($result === false) {
        echo "Не получилось выполнить функцию socket_connect().\nПричина: ($result) " . socket_strerror(socket_last_error($socket)) . "\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 "Отправка HTTP-запроса с заголовком HEAD...";
    socket_write($socket, $in, strlen($in));
    echo "OK.\n";

    echo "Чтение ответа:\n\n";
    $buf = 'Это мой буфер.';

    if (false !== ($bytes = socket_recv($socket, $buf, 2048, MSG_WAITALL))) {
        echo "Количество байтов, которое прочитала функции socket_recv(): {$bytes}. Закрываем сокет... ";
    } else {
        echo "Не получилось выполнить socket_recv(); причина: " . socket_strerror(socket_last_error($socket)) . "\n";
    }
    socket_close($socket);

    echo $buf . "\n";
    echo "OK.\n\n";

    ?>

Вывод приведённого примера будет похож на:

    <h2>Соединение по протоколу TCP/IP</h2>
    OK.
    Попытка соединиться с хостом '208.77.188.166' на порте '80'... OK.
    Отправка HTTP-запроса с заголовком HEAD... OK.
    Получение ответа:

    Количество байтов, которое прочитала функция socket_recv(): 14. Закрываем сокет... HTTP/1.1 200 OK
    Date: Mon, 14 Sep 2009 08:56:36 GMT
    Server: Apache/2.2.3 (Red Hat)
    Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT
    ETag: "b80f4-1b6-80bfd280"
    Accept-Ranges: bytes
    Content-Length: 438
    Connection: close
    Content-Type: text/html; charset=UTF-8

    OK.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open