In network programming, sometimes we need to send raw binary data to a remote server, especially when implementing certain protocols. PHP provides a very powerful function pack() that can package data into binary strings in a specified format. Combined with stream_socket_client() , we can easily send this raw data over a TCP or UDP connection.
This article will introduce in detail how to use PHP's pack() function to package data and send it to the specified server through stream_socket_client() .
The pack() function is used to convert data into binary strings. Its first parameter is the format string, and subsequent parameters are the data to be packaged. The format string contains various format codes, such as:
C — Unsigned characters (1 byte)
n — Unsigned short integer (2 bytes, large endian)
N — Unsigned long (4 bytes, big endian)
a — NUL character filled string
A — Space filled string
For example:
$data = pack('Cnn', 0x01, 300, 400);
Here 0x01 is a byte, and 300 and 400 are both 2 byte unsigned integers.
stream_socket_client() is used to create a network connection for the client and can support TCP, UDP and other protocols. Common syntaxes are as follows:
$socket = stream_socket_client("tcp://m66.net:12345", $errno, $errstr, 30);
The first parameter is the address, the format is tcp://domain name:port
The connection returns the resource successfully, and the failure returns false
$errno and $errstr will return error codes and error messages
The last parameter is the timeout time (seconds)
Through this connection, we can use fwrite() to send data and fread() to receive data.
Suppose we need to send a protocol packet to the server, the format is as follows:
1 byte command code, fixed to 0x10
2 bytes of user ID, big endian
4 byte timestamp, big endian
8 byte string (if less than 8 bytes, space padding)
PHP code example:
<?php
// Target server information
$host = "m66.net";
$port = 12345;
// create TCP connect
$socket = stream_socket_client("tcp://$host:$port", $errno, $errstr, 10);
if (!$socket) {
die("connect失败: $errstr ($errno)\n");
}
// Prepare data
$command = 0x10;
$userId = 1025;
$timestamp = time();
$username = "user123";
// Packaging data
// C - 1Byte unsigned integer
// n - 2Byte unsigned short integer(Big endian)
// N - 4Byte unsigned long integer(Big endian)
// A8 - The length is8string,Space filling
$packedData = pack('CnNA8', $command, $userId, $timestamp, $username);
// Send data
fwrite($socket, $packedData);
// Read server response(Assume that the server will return 4 Byte response code)
$response = fread($socket, 4);
if ($response !== false) {
$responseCode = unpack('N', $response)[1];
echo "Server response code: $responseCode\n";
} else {
echo "No server response received\n";
}
fclose($socket);
Using pack() can easily convert various data types into binary data, suitable for network transmission.
stream_socket_client() is used to create network connections and supports multiple protocols.
When sending binary data, ensure that both parties understand the protocol format consistently, especially the data length and byte order.
When reading data, unpack() should also be used to parse the original binary data.