PHPでネットワークをプログラミングする場合、ソケットプログラミングは一般的かつ基礎となる通信方法です。ブロッキングの読み取りが必要なシナリオの場合、 Socket_set_blockおよびsocket_read関数は、効率的で安定したデータ受信を実現するために合理的に使用されます。この記事では、これら2つの機能を例と組み合わせて詳細に使用するための手法を紹介します。
ブロッキングモード:読み取り関数を呼び出すとき、データの準備ができていない場合、プログラムはブロックされ、データが読み取り可能またはタイムアウトまで待機します。
非ブロッキングモード:読み取り関数はすぐに戻ります。データが読み取られない場合、空に戻るかエラーが戻り、プログラムは他のタスクを実行し続けることができます。
デフォルトでは、PHPソケットはブロッキングモードです。これは、HTTPリクエスト処理、チャットアプリケーションなど、データが完全に到着するのを待つ必要があるアプリケーションに適しています。
socket_set_block(リソース$ socket):bool
ソケットをブロッキングモードに設定します。この関数を呼び出した後、後続のsocket_readはデータが読み取られるまでブロックします。
socket_read(resource $ socket、int $ length、int $ type = php_binary_read):string | false
ソケットからデータを読み取ります。ブロッキングモードでデータがない場合は、データが到着するのを待ちます。非ブロッキングの場合、すぐに戻ります。
ブロッキングモードを設定<br> ソケットがsocket_set_block($ socket)を介してブロックされていることを確認して、読み取り中に継続的にポーリングするときにCPUを無駄にしないようにします。
読み取り長を合理的に指定します
socket_readの2番目の引数は、毎回読み取られるバイトの最大数を指定します。小さすぎると頻繁に通話が発生し、大きすぎると長い待ち時間が生じる可能性があります。
読み取り<br>を終了するための処理条件 通常、ブロックの読み取りには、特定のエンディング文字を読み取り、指定された長さを読み取って死んだループを避けるなど、終了条件が必要です。
エラーとタイムアウト処理<br> ブロッキングモードは待機しますが、永続的なブロッキングを防ぐために実際のアプリケーションでタイムアウトを設定する必要があります。 PHPソケット自体には直接のタイムアウトパラメーターはありませんが、 socket_selectで実装できます。
<?php
// 作成する TCP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("socket_create failed: " . socket_strerror(socket_last_error()));
}
// サーバーに接続します,ドメイン名をに置き換えます gitbox.net
$host = "gitbox.net";
$port = 80;
if (!socket_connect($socket, $host, $port)) {
die("socket_connect failed: " . socket_strerror(socket_last_error($socket)));
}
// ブロッキングモードを設定します
socket_set_block($socket);
// 簡単に送信できます HTTP リクエスト例
$request = "GET / HTTP/1.1\r\nHost: gitbox.net\r\nConnection: close\r\n\r\n";
socket_write($socket, $request, strlen($request));
// 応答データを読む
$response = '';
while (true) {
// ほとんどの読み物はです1024バイト
$buf = socket_read($socket, 1024, PHP_BINARY_READ);
if ($buf === false) {
echo "socket_read failed: " . socket_strerror(socket_last_error($socket));
break;
}
if ($buf === '') {
// 読み取りの終わり
break;
}
$response .= $buf;
}
// 出力サーバーの応答
echo $response;
// 閉鎖 socket
socket_close($socket);
?>
socket_set_blockを使用してブロッキングモードを設定した後、 socket_readはデータが到着するまでブロックし、高いCPU使用量を避けます。
読み取りの長さとループの出口条件は、効率的で安全なデータ受信を確保するために、読み取り中に合理的に設定する必要があります。
Socket_Selectと組み合わせて、プログラムの堅牢性を向上させるために、タイムアウトで読み取りをブロックすることができます。
上記の例では、HTTPリクエストを例として使用して、ブロッキングモードで完全な応答をスムーズに読み取る方法を実証します。
socket_set_blockおよびsocket_readと合理的に協力することにより、PHPソケットの読み取り値をより効率的かつ安定させることができ、データをブロックして待機する必要があるさまざまなネットワークアプリケーションに適しています。