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
$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) {
}$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() для корректного завершения соединения.
Для сокетов, открытых через потоковые функции вроде 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>
Метод socket.end() отправляет FIN-пакет, а socket.destroy() немедленно уничтожает сокет.
const net = require('net');
const socket = new net.Socket();
socket.end(); // Корректное закрытиеДля закрытия соединения с базой данных используется команда 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) {
}Расширенные примеры
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, 'example.com', 80);
// Сначала останавливаем передачу данных
socket_shutdown($socket, 2); // 2 = прекратить прием и отправку
// Затем закрываем сокет
socket_close($socket);
echo 'Сокет корректно закрыт';Сокет корректно закрыт
$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);Все соединения закрыты
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); // Вызовет деструкторСокет закрыт в деструкторе