現在の位置: ホーム> 最新記事一覧> ソケット通信のPack()アプリケーションの例

ソケット通信のPack()アプリケーションの例

M66 2025-06-03

PHPでソケット通信を実施するとき、特に特定のバイナリ形式でデータを転送する必要がある場合は、パッケージ化(カプセル化)してデータを開梱する必要がある状況に遭遇することがよくあります。 Pack()関数は、この問題を解決するための武器です。この記事では、ソケット通信におけるPACK()関数の特定の使用法を説明する簡単な例を組み合わせています。


Pack()機能とは何ですか?

pack()は、PHPの組み込み関数であり、指定された形式に従ってデータをバイナリ文字列にパッケージ化できます。これにより、処理されたデータはよりコンパクトで、ネットワーク上で送信するのに便利です。

基本的な構文は次のとおりです。

 string pack ( string $format , mixed $args [, mixed $... ] )
  • $フォーマットは、整数、文字、浮動ポイントなどのパッケージングルールを定義するフォーマット文字列です。

  • 後続のパラメーターは、対応する形式のデータです。


ソケット通信がpack()を必要とするのはなぜですか?

ソケット通信中、データはバイトストリームで送信されます。さまざまなマシンのエンディアン性は異なる場合があり、テキストまたは通常のデータを直接送信すると、受信者がエラーを解析する可能性があります。

pack()を使用できます:

  • 固定形式でデータをエンコードして、送信および受信先の形式が一貫していることを確認します。

  • エンディアンネスの問題を処理します(ビッグエンディアン、リトルエンディアン)。

  • 送信と解析を簡単にするために、固定長のバイナリデータを生成します。


ソケット通信でのpack()の適用を例で説明する

TCPソケットを介してデータパケットを送信すると、フォーマットは次のとおりです。

フィールドタイプ説明します
パッケージの長さ符号なしショート(2バイト)パッケージの長さフィールド自体を除くパッケージの長さ
コマンド番号符号なしショート(2バイト)コマンドID
データ特定のコンテンツ

コードの例を送信します

<?php
// 送信されたデータをシミュレートします
$command = 1001;
$data = "Hello, socket communication!";

// データの長さを計算します
$dataLen = strlen($data);

// パッケージの長さはコマンド番号の長さです + データの長さ (2 + $dataLen)
$packetLen = 2 + $dataLen;

// 使用 pack パッケージの長さとコマンド番号(ネットワークバイト順序を使用します,ビッグエンディアン)
$header = pack('n', $packetLen) . pack('n', $command);

// 完全なパッケージのスプライシング
$packet = $header . $data;

// 確立されていると仮定します socket 接続する,socket_write データを送信します
// socket_write($socket, $packet, strlen($packet));

echo "发送的二进制データの長さ: " . strlen($packet) . "\n";
echo "バイナリデータ16カテゴリ表現: " . bin2hex($packet) . "\n";
?>

分析手順

  • pack( 'n'、$ packetlen)とは、署名のない短い整数(2バイト)とネットワークエンディアン(ビッグエンディアン)に$ packetlenを梱包することを意味します。

  • パック( 'n'、$ command)同様に、コマンド番号をパックします。

  • スプライシング後、パッケージはデータコンテンツに従います。

レシーバー解析の例

データを受信した後、次のように解析できます。

 <?php
// 仮定 $recvData はいから socket バイナリデータをお読みください
// 例えば: $recvData = socket_read($socket, 1024);

// 最初にパッケージの長さとコマンド番号を解析します
$header = substr($recvData, 0, 4);
list($packetLen, $command) = array_values(unpack('npacketLen/command', $header));

// データコンテンツを抽出します
$data = substr($recvData, 4, $packetLen - 2);

echo "パッケージの長さ: $packetLen\n";
echo "コマンド番号: $command\n";
echo "データコンテンツ: $data\n";
?>

まとめ

  • Pack()関数は、バイナリデータパッケージの強力なツールであり、さまざまなネットワークプロトコルとバイナリファイル操作に適しています。

  • ソケット通信では、 Pack()の合理的な使用は、一貫したデータ形式と安定した通信を確保できます。

  • Unpack()関数と組み合わせると、バイナリデータの解析を簡単に実行できます。

  • エンディアンネスの問題に特に注意してください。ネットワーク通信は一般に、ネットワークのエンディアンネス(ビッグエンディアンネス)を採用しており、 「n」形式を使用して短い整数をパッケージ化することが最も一般的です。

バイナリプロトコルに基づいてネットワーク通信を行っている場合は、 pack()unpack()をさらに練習することを強くお勧めします。これにより、パケットを処理する能力が大幅に向上します。