PHPを使用してソケットベースのネットワークアプリケーションを開発する場合、開発者はしばしば2つの機能と接触します: socket_accept()とsocket_set_block() 。どちらの機能もPHPソケット拡張に属しますが、それらの使用に密接に関連しています。彼らの共同作業メカニズムを理解することは、ソケットの動作をより正確に制御し、ネットワーク通信の信頼性と効率を改善するのに役立ちます。
これら2つの機能のコラボレーションを調査する前に、まずそれらの基本機能を理解しましょう。
socket_accept(リソース$ socket):リソース| false
この関数は、リスニングソケットからの接続要求を受け入れるために使用されます。接続要求がない場合、その動作はソケットのブロッキングパターンに依存します。
socket_set_block(リソース$ socket):bool
この関数は、ソケットをブロッキングモードに設定します。ブロッキングモードでは、関連するソケット操作( socket_accept 、 socket_readなど)がデータまたは接続が発生するまで待ちます。
socket_set_block()の反対はsocket_set_nonblock()です。これにより、データまたは接続があるかどうかに関係なく、ソケット操作がすぐに戻ります。
デフォルトでは、PHPによって作成されたソケットはブロッキングモードにあります。つまり、 Socket_Accept()はブロックされ、クライアント接続が発生するまで待機します。つまり、次のコードを実行した場合:
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket);
$client = socket_accept($socket);
echo "Connection accepted";
クライアント接続がなければ、プログラムは接続が発生するまでsocket_accept()呼び出しで停止します。
ここで、 socket_set_block()を導入し、Socketをブロックモードに明示的に設定します(デフォルトでブロックしていますが、明示的な設定は、モードを変更した以前の操作によりコードのエラーを防ぐことができます):
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_block($socket); // ブロッキングモードに明示的に設定されています
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket);
$client = socket_accept($socket);
echo "Connection accepted";
この時点で、 socket_accept()の動作は変更されません。クライアント接続が発生するまでブロックされます。
ただし、 socket_set_nonblock()を使用する場合:
socket_set_nonblock($socket);
Socket_accept()が呼び出されると、接続要求がない場合、すぐにFalseを返し、 Socket_last_error()をEagainまたはewouldblockのためであるかどうかを確認できます。
socket_set_block()とsocket_accept()のコラボレーションは、ソケットの動作モードを設定してsocket_accept()のブロッキング動作を決定することによって基本的に決定されます。この設定により、プログラムの制御フローが同期(ブロッキング)か非同期(非ブロッキング)かが決まります。
たとえば、高性能サーバーを作成するときは、非ブロッキングソケットを使用し、 socket_select()を組み合わせて複数の接続要求をリッスンする場合があります。
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($socket);
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket);
$clients = [];
while (true) {
$read = [$socket];
$write = $except = null;
if (socket_select($read, $write, $except, 1) > 0) {
$client = socket_accept($socket);
if ($client !== false) {
$clients[] = $client;
echo "Client connected\n";
}
}
// 他のロジックを処理します
}
この方法により、 socket_accept()をブロックして待機せずに、ループで複数のソケットを同時に処理できます。
socket_set_block() Socketブロックが機能するかどうかを決定し、 socket_accept()がこの設定の影響を受ける特定の操作です。ソケットがブロックモードの場合、 socket_accept()が接続を待ちます。非ブロッキングモードでは、すぐに戻ります。 2つの共同使用により、実際のニーズに応じて同期または非同期ネットワークサービスプログラムを作成することができ、柔軟性が向上します。
彼らの関係を理解することは、安定したソケットサービスの書き込みに役立つだけでなく、高い集団通貨と低遅延のネットワークアプリケーションを構築するための基盤を置いています。
関連する例については、 https://gitbox.net/socket-examplesを参照してください。