現在の位置: ホーム> 最新記事一覧> phpのpack()関数を使用して、stream_socket_client()と併せて生データを送信する方法は?

phpのpack()関数を使用して、stream_socket_client()と併せて生データを送信する方法は?

M66 2025-06-04

ネットワークプログラミングでは、特に特定のプロトコルを実装する場合は、RAWバイナリデータをリモートサーバーに送信する必要がある場合があります。 PHPは、指定された形式でデータをバイナリ文字列にパッケージ化できる非常に強力な機能パック()を提供します。 Stream_Socket_Client()と組み合わせて、この生データをTCPまたはUDP接続を介して簡単に送信できます。

この記事では、PHPのPack()関数を使用してデータをパッケージ化し、 Stream_Socket_Client()を介して指定されたサーバーに送信する方法を詳細に紹介します。


1。Pack()関数の紹介

Pack()関数は、データをバイナリ文字列に変換するために使用されます。その最初のパラメーターはフォーマット文字列であり、その後のパラメーターはパッケージ化されるデータです。フォーマット文字列には、次のようなさまざまなフォーマットコードが含まれています。

  • C - 署名されていない文字(1バイト)

  • n - 署名されていない短い整数(2バイト、大きなエンディアン)

  • n - 署名の長いロング(4バイト、ビッグエンディアン)

  • a - nul文字塗りつぶされた文字列

  • A - スペースが充填された文字列

例えば:

 $data = pack('Cnn', 0x01, 300, 400);

ここでは、 0x01はバイトで、 300400は両方とも2バイトの署名されていない整数です。


2。Stream_Socket_Client()の紹介

Stream_Socket_Client()は、クライアントのネットワーク接続を作成するために使用され、TCP、UDP、およびその他のプロトコルをサポートできます。一般的な構文は次のとおりです。

 $socket = stream_socket_client("tcp://m66.net:12345", $errno, $errstr, 30);
  • 最初のパラメーターはアドレス、形式はtcp:// domain name:portです

  • 接続がリソースを正常に返し、障害がfalseを返します

  • $ errnoおよび$ errstrはエラーコードとエラーメッセージを返します

  • 最後のパラメーターはタイムアウト時間(秒)です

この接続を通じて、 fwrite()を使用してデータとfread()を送信してデータを受信できます。


3。例:pack()と送信を備えたパッケージデータ

プロトコルパケットをサーバーに送信する必要があると仮定すると、フォーマットは次のとおりです。

  • 0x10に固定された1バイトコマンドコード

  • 2バイトのユーザーID、Big Endian

  • 4バイトタイムスタンプ、ビッグエンディアン

  • 8バイト文字列(8バイト未満の場合、スペースパディング)

PHPコードの例:

 <?php

// ターゲットサーバー情報
$host = "m66.net";
$port = 12345;

// 作成する TCP 接続する
$socket = stream_socket_client("tcp://$host:$port", $errno, $errstr, 10);
if (!$socket) {
    die("接続する失败: $errstr ($errno)\n");
}

// データを準備します
$command = 0x10;
$userId = 1025;
$timestamp = time();
$username = "user123";

// パッケージングデータ
// C - 1バイト符号なし整数
// n - 2バイト符号なしショート整数(ビッグエンディアン)
// N - 4バイト符号なしの長い整数(ビッグエンディアン)
// A8 - 長さはです8弦,スペース充填
$packedData = pack('CnNA8', $command, $userId, $timestamp, $username);

// データを送信します
fwrite($socket, $packedData);

// サーバーの応答を読み取ります(サーバーが返されると仮定します 4 バイト応答コード)
$response = fread($socket, 4);
if ($response !== false) {
    $responseCode = unpack('N', $response)[1];
    echo "サーバー応答コード: $responseCode\n";
} else {
    echo "サーバーの応答は受信されていません\n";
}

fclose($socket);

4。キーポイントの概要

  • Pack()を使用すると、さまざまなデータ型をネットワーク伝送に適したバイナリデータに簡単に変換できます。

  • Stream_Socket_Client()は、ネットワーク接続を作成し、複数のプロトコルをサポートするために使用されます。

  • バイナリデータを送信するときは、両当事者がプロトコル形式、特にデータの長さとバイトの順序を一貫して理解していることを確認してください。

  • データを読み取るときは、 unpack()を使用して元のバイナリデータを解析する必要があります。