Socket set option: примеры (PHP)
socket_set_option(resource socket, int level, int optname, mixed optval): boolФункция socket_set_option
Функция socket_set_option используется для установки различных параметров работы сокета. Она позволяет настраивать низкоуровневые характеристики сетевого соединения, такие как таймауты, размеры буферов и флаги поведения сокета. Эта функция применяется при необходимости тонкой настройки сетевой связи для повышения производительности или надежности.
Функция принимает четыре аргумента:
- socket (тип Socket) – ресурс сокета, созданный функцией
socket_create. - level (тип int) – уровень, на котором устанавливается опция. Распространенные значения:
SOL_SOCKET,IPPROTO_TCP,IPPROTO_IP,IPPROTO_IPV6. - option (тип int) – идентификатор устанавливаемой опции. Примеры:
SO_REUSEADDR,SO_RCVTIMEO,TCP_NODELAY. - value (тип mixed) – значение опции. Может быть массивом, целым числом, булевым значением или другой структурой в зависимости от опции.
Функция возвращает true при успехе и false при ошибке.
Краткие примеры использования
Установка таймаута в 5 секунд для операции чтения.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$timeout = ['sec' => 5, 'usec' => 0];
$result = socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $timeout);
var_dump($result);bool(true)
Позволяет повторно использовать адрес сокета после закрытия соединения.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
var_dump($result);bool(true)
Установка опции TCP_NODELAY для немедленной отправки небольших пакетов.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8080);
$result = socket_set_option($socket, IPPROTO_TCP, TCP_NODELAY, 1);
var_dump($result);bool(true)
Альтернативные функции в PHP
Функция для получения текущего значения опции сокета. Используется, когда необходимо прочитать параметры сокета, установленные ранее.
Позволяет устанавливать опции для потоков (streams). Предпочтительнее для работы с высокоуровневыми потоками ввода-вывода (файлы, HTTP-соединения), в то время как socket_set_option предназначена для низкоуровневых сокетов.
Создает сокет с определенными параметрами. Некоторые базовые настройки можно задать при создании, но для тонкой настройки требуется socket_set_option.
Аналоги в других языках
Метод setsockopt объекта сокета выполняет аналогичную функцию. Отличие в том, что уровни и опции задаются константами из модуля socket.
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print(sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR))1
В Node.js настройки сокета часто устанавливаются отдельными методами. Например, для отключения алгоритма Нейгла используется метод setNoDelay.
const net = require('net');
const socket = new net.Socket();
socket.setNoDelay(true);
console.log(socket.noDelay);true
В языке C используется функция setsockopt с аналогичной сигнатурой. PHP-функция является оберткой над этим системным вызовом.
Типичные ошибки
Попытка установить опцию на ресурсе, который не является сокетом или уже закрыт.
$socket = false;
$result = socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
if ($result === false) {
echo "Ошибка: " . socket_strerror(socket_last_error());
}Ошибка: Invalid argument
Использование неверной комбинации уровня и опции.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_set_option($socket, SOL_SOCKET, TCP_NODELAY, 1); // TCP_NODELAY относится к IPPROTO_TCP
var_dump($result);bool(false)
Передача значения в неверном формате, например, числа вместо массива для таймаута.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, 5);
var_dump($result);bool(false)
Изменения в версиях PHP
В PHP 8.0.0 тип параметра socket изменен с resource на Socket (объект). В более ранних версиях функция принимала ресурс. Это изменение является частью общей типизации объектов в PHP 8.
Версия PHP 7.3 добавила поддержку опции TCP_NOPUSH на уровне IPPROTO_TCP для некоторых систем.
Рекомендуется использовать актуальную версию PHP для доступа ко всем возможным опциям и корректной работы типов.
Расширенные примеры
Увеличение размера буфера отправки до 64 КБ для улучшения производительности при передаче больших объемов данных.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, 'example.com', 80);
$result = socket_set_option($socket, SOL_SOCKET, SO_SNDBUF, 65536);
var_dump($result);
$bufferSize = socket_get_option($socket, SOL_SOCKET, SO_SNDBUF);
var_dump($bufferSize);bool(true) int(131072) // Значение может быть удвоено ядром
Установка нескольких опций сокета с помощью цикла.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$options = [
[SOL_SOCKET, SO_REUSEADDR, 1],
[SOL_SOCKET, SO_KEEPALIVE, 1],
[IPPROTO_TCP, TCP_NODELAY, 1]
];
foreach ($options as $option) {
socket_set_option($socket, $option[0], $option[1], $option[2]);
}
echo "Опции установлены";Опции установлены
Пример настройки сокета для приема мультикастного трафика с определенного адреса.
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '0.0.0.0', 12345);
$group = ip2long('224.0.0.100');
$result = socket_set_option($socket, IPPROTO_IP, MCAST_JOIN_GROUP, ['group' => $group, 'interface' => 0]);
var_dump($result);bool(true)
Установка опции для IPv6 сокета, например, добавление в мультикастную группу.
$socket = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '::', 12345);
$group = inet_pton('ff02::1');
$result = socket_set_option($socket, IPPROTO_IPV6, MCAST_JOIN_GROUP, ['group' => $group, 'interface' => 0]);
var_dump($result);bool(true)