ネットワークプログラミングにPHPを使用する場合、 Stream_Socket_RecvFrom関数は、UDPパケットを受信するために一般的に使用される関数です。ただし、デフォルトでは、この関数はデータが受信されるか、エラーが発生するまでデータを待機している間にブロックされます。シナリオでは、プログラムに長期的な一時停止を引き起こし、パフォーマンスとユーザーエクスペリエンスに影響します。この長いブロッキングを避けるために、読み取りタイムアウトを設定する必要があります。
この記事では、 Stream_Socket_RecvFrom関数で読み取りタイムアウトを設定する方法を詳細に説明し、プログラムの動作をよりよく制御するのに役立ちます。
stream_socket_recvfrom関数の基本的な使用法は次のとおりです。
$data = stream_socket_recvfrom($socket, 1024);
指定された$ソケットから最大1024バイトのデータを読み取ります。データが届かない場合、関数はブロックして待機します。
Stream_Socket_recvfromが呼び出されると、ピアが長い間データを送信しない場合、プログラムは待機します。これは、ネットワークアプリケーションの応答速度と安定性に非常に不利です。プログラムが長い間立ち往生しているのを避けるために、タイムアウトメカニズムを設定する必要があり、タイムアウトがタイムアウトしたら、読み取りをあきらめて他の処理を実行します。
PHPでは、通常、操作ストリームタイムアウトは、 stream_set_timeout関数を介して実装されます。この関数は、オープンストリームのタイムアウト時間を設定できます。
例:
// 作成する UDP socket
$socket = stream_socket_server("udp://0.0.0.0:9999", $errno, $errstr, STREAM_SERVER_BIND);
if (!$socket) {
die("无法作成するsocket: $errstr ($errno)\n");
}
// タイムアウトを設定します,2番単位とマイクロ2番単位
// 这里タイムアウトを設定します时间为 5 2番
stream_set_timeout($socket, 5);
// 読み取り関数を呼び出します
$data = stream_socket_recvfrom($socket, 1024);
$info = stream_get_meta_data($socket);
if ($info['timed_out']) {
echo "データのタイムアウトを読んでください,待っているのをあきらめる\n";
} else {
echo "受信したデータ: $data\n";
}
stream_set_timeout($ socket、5)は、 5秒のタイムアウトを設定します。
データを読んだ後、Timeoutがstream_get_meta_data($ socket)によって達成されるかどうかを判断します。
タイムアウトメカニズムに加えて、もう1つの一般的な実践は、ソケットを非ブロッキングモードに設定し、ポーリングまたはイベント駆動型メカニズムと併せてデータを読み取ることです。
// 作成する socket
$socket = stream_socket_server("udp://0.0.0.0:9999", $errno, $errstr, STREAM_SERVER_BIND);
if (!$socket) {
die("无法作成するsocket: $errstr ($errno)\n");
}
// 非ブロッキングモードを設定します
stream_set_blocking($socket, false);
$startTime = time();
$timeout = 5; // 2番
while (true) {
$data = stream_socket_recvfrom($socket, 1024);
if ($data !== false && $data !== '') {
echo "受信したデータ: $data\n";
break;
}
if (time() - $startTime > $timeout) {
echo "タイムアウトを読んでください,ループを終了します\n";
break;
}
// 避けるCPU占有が高すぎる,適切に眠ります
usleep(100000); // 100毫2番
}
この方法により、読み取りロジックのより柔軟な制御が可能になり、イベントループの統合が容易になります。
stream_socket_recvfromデフォルトでブロックされます。これにより、プログラムが長い間待つことがあります。
Stream_set_timeoutを使用して、タイムアウト時間を設定して、ブロッキングが長すぎないようにします。
読んだ後、 Stream_get_meta_dataを使用して、タイムアウトに到達するかどうかを判断します。
非ブロッキングモードを使用して、ポーリングで読み取り時間を制御することもできます。
タイムアウトパラメーターを合理的に設定することは、ネットワークプログラムの安定した応答を確保するための鍵です。