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

Функция socket_close: работа с сокетами в PHP
Раздел: Сокеты
socket_close(resource socket): void

Функция socket_close в PHP

Назначение

Функция socket_close() предназначена для завершения работы и освобождения ресурсов сокета, созданного функцией socket_create() или принятого функцией socket_accept(). Она закрывает соединение и делает дескриптор сокета непригодным для последующего использования.

Аргументы

Функция принимает один обязательный параметр:

  • $socket (Socket) — ресурс сокета, который требуется закрыть. Это должен быть валидный экземпляр класса Socket, созданный в PHP 8.0 и выше.

Функция не возвращает значения. После выполнения ресурс сокета освобождается.

Примеры использования socket_close

Закрытие TCP сокета клиента
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8080);
socket_write($socket, "GET / HTTP/1.1\r\n\r\n");

// Закрытие сокета
socket_close($socket);

var_dump($socket);
object(Socket)#1 (0) {
}
Закрытие UDP сокета
$udpSocket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($udpSocket, '127.0.0.1', 12345);

// После завершения работы
socket_close($udpSocket);

echo 'UDP сокет закрыт';
UDP сокет закрыт

Альтернативные функции в PHP

Функция socket_shutdown() останавливает прием, отправку или оба типа передачи данных через сокет, но не освобождает ресурс. Её рекомендуется вызывать перед socket_close() для корректного завершения соединения.

fclose для потоков

Для сокетов, открытых через потоковые функции вроде fsockopen(), используется функция fclose(). Она закрывает поток и связанный с ним ресурс сокета.

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

Socket close в Python

Метод socket.close() закрывает сокет. В отличие от PHP, сокет автоматически закрывается при удалении объекта.

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.close()
print(s)
<socket.socket [closed] fd=-1>
Node.js (JavaScript)

Метод socket.end() отправляет FIN-пакет, а socket.destroy() немедленно уничтожает сокет.

const net = require('net');
const socket = new net.Socket();
socket.end(); // Корректное закрытие
MySQL

Для закрытия соединения с базой данных используется команда CLOSE или метод закрытия в API конкретного языка, например mysql_close() в старом расширении PHP.

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

Попытка повторного закрытия
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_close($socket);
socket_close($socket); // Ошибка
Warning: socket_close(): supplied resource is not a valid Socket resource
Использование закрытого сокета
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_close($socket);
$result = socket_write($socket, 'data'); // Ошибка
Warning: socket_write(): supplied resource is not a valid Socket resource
Передача некорректного ресурса
$invalid = fopen('file.txt', 'r');
socket_close($invalid);
Warning: socket_close(): supplied resource is not a valid Socket resource

Изменения в PHP 8

В PHP 8.0 параметр функции socket_close() теперь принимает объект класса Socket вместо ресурса (resource). Это часть общей миграции с ресурсов на объекты.

// До PHP 8.0 - ресурс
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
var_dump($socket);

// Начиная с PHP 8.0 - объект
var_dump($socket);
// До PHP 8.0
resource(4) of type (Socket)

// PHP 8.0 и выше
object(Socket)#1 (0) {
}

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

Закрытие сокета с предварительной остановкой
Пример php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, 'example.com', 80);

// Сначала останавливаем передачу данных
socket_shutdown($socket, 2); // 2 = прекратить прием и отправку

// Затем закрываем сокет
socket_close($socket);

echo 'Сокет корректно закрыт';
Сокет корректно закрыт
Обработка множественных соединений
Пример php
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($server, '127.0.0.1', 8080);
socket_listen($server);

$connections = [];
for ($i = 0; $i < 3; $i++) {
    $client = socket_accept($server);
    $connections[] = $client;
    socket_write($client, "Привет $i\n");
}

// Закрытие всех клиентских сокетов
foreach ($connections as $conn) {
    socket_close($conn);
}

// Закрытие серверного сокета
socket_close($server);
Все соединения закрыты
Использование в классе с деструктором
Пример php
class SocketHandler {
    private $socket;
    
    public function __construct() {
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    }
    
    public function __destruct() {
        if ($this->socket instanceof Socket) {
            socket_close($this->socket);
            echo 'Сокет закрыт в деструкторе';
        }
    }
}

$handler = new SocketHandler();
unset($handler); // Вызовет деструктор
Сокет закрыт в деструкторе

PHP socket_close function comments

En
Socket close Closes a socket resource