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

Использование socket_write для записи данных в сокеты PHP
Раздел: Сокеты
socket_write(resource socket, string buffer [, int length]): int|false

Функция socket_write в PHP

Общее описание

Функция socket_write используется для записи данных в сокет. Она применяется в низкоуровневом сетевом программировании для отправки информации через установленное сетевое соединение. Функция работает с сокетами, созданными функциями socket_create или принятыми socket_accept.

Аргументы функции
  • $socket (обязательный) - ресурс сокета, полученный из socket_create или socket_accept.
  • $data (обязательный) - строка с данными для отправки через сокет.
  • $length (необязательный) - максимальное количество байт для записи. Если параметр не указан, функция записывает все данные из строки.

Функция возвращает количество успешно записанных байт или false в случае ошибки.

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

Базовый пример записи в сокет
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8080);
$data = "Hello Server";
$bytes = socket_write($socket, $data);
echo "Written: $bytes bytes";
socket_close($socket);
?>
Written: 12 bytes
Запись с ограничением длины
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8080);
$data = "Hello Server";
$bytes = socket_write($socket, $data, 5);
echo "Written: $bytes bytes";
socket_close($socket);
?>
Written: 5 bytes
Обработка ошибки записи
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
// Не выполняем подключение
$data = "Test";
$result = socket_write($socket, $data);
if ($result === false) {
    echo "Write failed: " . socket_strerror(socket_last_error($socket));
}
socket_close($socket);
?>
Write failed: Transport endpoint is not connected

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

fwrite для потоков сокетов

Функция fwrite работает с сокетами, открытыми через stream_socket_client. Она более удобна при работе с потоковыми контекстами.

stream_socket_sendto для датаграмм

Функция stream_socket_sendto используется для отправки данных на адрес без установления соединения, что подходит для UDP-сокетов.

socket_send для расширенного контроля

Функция socket_send предоставляет больше контроля над отправкой данных через флаги, такие как MSG_OOB или MSG_EOR.

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

Python: метод send
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 8080))
bytes_sent = s.send(b'Hello Server')
print(f'Sent: {bytes_sent} bytes')
s.close()
Sent: 12 bytes
Node.js: метод write
const net = require('net');
const client = new net.Socket();
client.connect(8080, '127.0.0.1', () => {
    const bytes = client.write('Hello Server');
    console.log(`Written: ${bytes} bytes`);
});
Written: 12 bytes
Java: OutputStream.write
import java.net.*;
import java.io.*;
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream out = socket.getOutputStream();
out.write("Hello Server".getBytes());
out.flush();
socket.close();

Типичные ошибки при использовании

Запись в закрытый сокет
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_close($socket);
$result = socket_write($socket, "data");
if ($result === false) {
    echo "Error: " . socket_strerror(socket_last_error($socket));
}
?>
Error: Bad file descriptor
Некорректный тип данных
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_write($socket, null);
if ($result === false) {
    echo "Error with null data";
}
?>
Error with null data
Превышение размера буфера
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8080);
$largeData = str_repeat("A", 1000000);
$bytes = socket_write($socket, $largeData);
echo "Written: $bytes bytes";
?>
Written: 1000000 bytes (может зависеть от настроек системы)

Изменения в последних версиях PHP

В PHP 8.0 функция socket_write не претерпела значительных изменений. Однако в PHP 8.1 улучшена обработка ошибок для всех функций сокетов, включая более четкие сообщения об ошибках. В PHP 8.2 изменений в поведении функции не было.

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

Постепенная отправка большого объема данных
Пример php
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 9000);

$largeData = str_repeat("DataPacket", 10000);
$chunkSize = 1024;
$totalWritten = 0;

for ($i = 0; $i < strlen($largeData); $i += $chunkSize) {
    $chunk = substr($largeData, $i, $chunkSize);
    $written = socket_write($socket, $chunk);
    if ($written === false) break;
    $totalWritten += $written;
    usleep(1000); // Небольшая пауза
}

echo "Total written: $totalWritten bytes";
socket_close($socket);
?>
Total written: 100000 bytes
Работа с неблокирующими сокетами
Пример php
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($socket);
socket_connect($socket, '127.0.0.1', 8080);

$data = "Non-blocking data";
$written = socket_write($socket, $data);

if ($written === false) {
    $error = socket_last_error($socket);
    if ($error == SOCKET_EAGAIN || $error == SOCKET_EWOULDBLOCK) {
        echo "Socket buffer is full";
    }
} else {
    echo "Written: $written bytes";
}

socket_close($socket);
?>
Written: 17 bytes (или Socket buffer is full)
Отправка бинарных данных
Пример php
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8080);

$binaryData = pack('Nn', 123456, 7890); // 32-битное и 16-битное числа
$bytes = socket_write($socket, $binaryData);

echo "Binary data sent: $bytes bytes";
socket_close($socket);
?>
Binary data sent: 6 bytes
Использование с socket_select
Пример php
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '127.0.0.1', 8080);

$data = "Select example";
$write = [$socket];
$except = null;

if (socket_select($read = null, $write, $except, 5) > 0) {
    $bytes = socket_write($socket, $data);
    echo "Written via select: $bytes bytes";
} else {
    echo "Socket not ready for writing";
}

socket_close($socket);
?>
Written via select: 14 bytes

PHP socket_write function comments

En
Socket write Write to a socket