Socket getsockname: примеры (PHP)

Работа с сетевыми адресами через socket_getsockname
Раздел: Сокеты
socket_getsockname(resource socket, string &address [, int &port]): bool

Описание socket_getsockname

Назначение

Функция socket_getsockname в PHP получает информацию о локальной стороне установленного сокетного соединения. Её применяют для определения IP-адреса и порта, назначенных системе при работе с сетевыми соединениями.

Аргументы
  • socket (обязательный) - ресурс сокета, созданный socket_create().
  • address (обязательный) - ссылка на переменную, в которую запишется IP-адрес или Unix-сокет путь.
  • port (опциональный) - ссылка на переменную для номера порта (используется только для AF_INET и AF_INET6).

Примеры применения

Базовый пример TCP-сервера
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '127.0.0.1', 0);
socket_listen($socket);
socket_getsockname($socket, $addr, $port);
echo "Сервер слушает: $addr:$port";
?>
Сервер слушает: 127.0.0.1:56789
UDP-сокет без порта
<?php
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '0.0.0.0', 0);
if(socket_getsockname($socket, $addr, $port)) {
    echo "Адрес: $addr, Порт: $port";
}
?>
Адрес: 0.0.0.0, Порт: 49152

Альтернативы в PHP

Получает информацию об удаленной стороне соединения. Используется, когда требуется узнать адрес клиента.

stream_socket_get_name

Работает с потоковыми сокетами, созданными через stream_socket. Предоставляет аналогичную функциональность.

Выбор функции

socket_getsockname применяют для низкоуровневых сокетов, а stream_socket_get_name - для потоков в стиле PHP.

Аналоги в других языках

Socket getsockname в Python

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 0))
addr, port = sock.getsockname()
print(f'{addr}:{port}')
127.0.0.1:65432
Node.js
const net = require('net');
const server = net.createServer();
server.listen(0, '127.0.0.1');
server.on('listening', () => {
    const addr = server.address();
    console.log(`${addr.address}:${addr.port}`);
});
127.0.0.1:56789
Отличия

В Python и JavaScript методы встроены в объекты сокетов, а в PHP требуется отдельный вызов функции.

Типичные ошибки

Некорректный ресурс
<?php
$addr = '';
socket_getsockname(false, $addr);
?>
Warning: socket_getsockname() expects parameter 1 to be resource, bool given
Сокет без привязки
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_getsockname($socket, $addr, $port);
?>
Warning: socket_getsockname(): unable to fetch socket name
Неправильная передача аргументов
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_getsockname($socket, null);
?>
Warning: socket_getsockname() expects parameter 2 to be string, null given

Изменения в PHP

В PHP 8.0 функция теперь выбрасывает ValueError при некорректных аргументах вместо генерации предупреждений. С PHP 8.0 параметры address и port всегда передаются по ссылке.

Расширенные примеры

Множественные интерфейсы
Пример php
<?php
$socket = socket_create(AF_INET6, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '::', 0);
socket_getsockname($socket, $addr, $port);
$ipv4 = socket_getsockname($socket, $addr);
echo "IPv6: $addr:$port\n";
?>
IPv6: :: 34567
Unix-сокеты
Пример php
<?php
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
socket_bind($socket, '/tmp/test.sock');
socket_getsockname($socket, $path);
echo "Путь: $path";
?>
Путь: /tmp/test.sock
Диагностика после соединения
Пример php
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, 'example.com', 80);
socket_getsockname($socket, $local_ip, $local_port);
echo "Локальный адрес подключения: $local_ip:$local_port";
?>
Локальный адрес подключения: 192.168.1.5:49210
Сравнение интерфейсов
Пример php
<?php
$sockets = [];
foreach(['0.0.0.0', '127.0.0.1'] as $bind_addr) {
    $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    socket_bind($sock, $bind_addr, 0);
    socket_getsockname($sock, $addr, $port);
    $sockets[] = [$addr, $port];
}
print_r($sockets);
?>
Array
(
    [0] => Array
        (
            [0] => 0.0.0.0
            [1] => 49153
        )
    [1] => Array
        (
            [0] => 127.0.0.1
            [1] => 49154
        )
)

PHP socket_getsockname function comments

En
Socket getsockname Queries the local side of the given socket which may either result in host/port or in a Unix filesystem path, dependent on its type