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 работает с сокетами, открытыми через stream_socket_client. Она более удобна при работе с потоковыми контекстами.
Функция stream_socket_sendto используется для отправки данных на адрес без установления соединения, что подходит для UDP-сокетов.
Функция socket_send предоставляет больше контроля над отправкой данных через флаги, такие как MSG_OOB или MSG_EOR.
Аналоги в других языках программирования
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
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
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
$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
$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
$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
<?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