PHPでは、ネットワークを通信する場合、TCPプロトコルを介してクライアントとサーバーの間に接続を確立する必要があることがよくあります。接続の動作を制御するために、異なるソケットオプションを使用して、ネットワーク通信を非ブロックまたはブロックすることを実現できます。 socket_set_blockは、ソケットをブロッキングモードに設定するのに役立つ非常に重要な機能の1つです。これは、特定のネットワーク通信のニーズに非常に役立ちます。
ネットワークプログラミングでは、ブロッキングモードと非ブロッキングモードがソケット操作を実行するときにプログラムの動作を決定します。
ブロッキングモード:このモードでは、プログラムは操作が完了するのを待ち(読み取りや執筆など)、操作が成功するか、エラーが発生するまで実行され続けません。これは、読み取るデータがない場合、プログラムが待機することを意味します。
非ブロッキングモード:このモードでは、プログラムは操作が完了するのを待ちません。データが一時的に利用できない場合、ソケット操作はすぐにエラーまたは特定のステータス値を返し、プログラムが他のタスクを実行し続けることができます。
Socket_set_block関数は、ブロッキングモードに作成されたソケットを設定するために使用されます。これは、特定のネットワークリクエストを処理する場合、特にプログラムがデータが正常に返されるのを待つ場合に非常に便利です。 Socket_set_block関数は、特定のブロッキング動作を指定するために追加のパラメーターを必要としないことに注意する必要があります。 1回の呼び出しでソケットをブロッキングモードに設定します。
<span><span><span class="hljs-keyword">bool</span></span><span> </span><span><span class="hljs-title function_ invoke__">socket_set_block</span></span><span> ( resource </span><span><span class="hljs-variable">$socket</span></span><span> );
</span></span>
$ソケット:ブロッキングモードに設定するソケットリソース。
この関数は、設定が成功したことを示すために真で戻り、 falsを返して設定が失敗したことを示します。設定が失敗した場合、 socket_last_error()を使用して特定のエラー情報を取得できます。
Socket_set_blockを使用してTCP接続をブロッキングモードに設定する方法を示す簡単な例を次に示します。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 作成する TCP ソケット</span></span><span>
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_create</span></span><span>(AF_INET, SOCK_STREAM, SOL_TCP);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$socket</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Socket 作成する失败: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">socket_strerror</span></span><span>(</span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>()) . </span><span><span class="hljs-string">"\n"</span></span><span>;
</span><span><span class="hljs-keyword">exit</span></span><span>;
}
</span><span><span class="hljs-comment">// ターゲットサーバーに接続します</span></span><span>
</span><span><span class="hljs-variable">$address</span></span><span> = </span><span><span class="hljs-string">'127.0.0.1'</span></span><span>;
</span><span><span class="hljs-variable">$port</span></span><span> = </span><span><span class="hljs-number">8080</span></span><span>;
</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_connect</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-variable">$address</span></span><span>, </span><span><span class="hljs-variable">$port</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$result</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"接続に失敗しました: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">socket_strerror</span></span><span>(</span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>()) . </span><span><span class="hljs-string">"\n"</span></span><span>;
</span><span><span class="hljs-keyword">exit</span></span><span>;
}
</span><span><span class="hljs-comment">// 将ソケット设置为阻塞模式</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">socket_set_block</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"ソケット已成功设置为阻塞模式。\n"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"设置ソケット为阻塞模式失败。\n"</span></span><span>;
</span><span><span class="hljs-keyword">exit</span></span><span>;
}
</span><span><span class="hljs-comment">// データを送信します</span></span><span>
</span><span><span class="hljs-variable">$message</span></span><span> = </span><span><span class="hljs-string">"Hello, Server!"</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">socket_write</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-variable">$message</span></span><span>, </span><span><span class="hljs-title function_ invoke__">strlen</span></span><span>(</span><span><span class="hljs-variable">$message</span></span><span>));
</span><span><span class="hljs-comment">// 応答を受け取ります</span></span><span>
</span><span><span class="hljs-variable">$response</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_read</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-number">1024</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"サーバーの応答: <span class="hljs-subst">$response</span></span></span><span>\n";
</span><span><span class="hljs-comment">// 关闭ソケット</span></span><span>
</span><span><span class="hljs-title function_ invoke__">socket_close</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>
この例では、最初にTCPソケットを作成し、 Socket_Connectを介してサーバーに接続します(IPが127.0.0.1 、ポートが8080であると仮定)。次に、 socket_set_blockを使用してソケットをブロッキングモードに設定し、メッセージを送信してサーバーの応答を待ちます。
ブロッキングモードの影響:
ブロッキングモードでは、 socket_readやsocket_writeなどの操作が完了またはタイムアウトまで現在のプロセスをブロックします。したがって、無反応の接続を長時間処理する場合、プログラムは反応しないようになる可能性があります。
サーバー側の応答速度が制御可能であることを確認する必要があります。そうしないと、ブロッキングモードは、高遅延または不安定な接続を備えたネットワーク環境で深刻なパフォーマンスボトルネックにつながる可能性があります。
非ブロッキングモードでの切り替え:
ソケットを非ブロッキングモードに設定した場合( Socket_set_nonblock関数を介して)、 socket_set_blockを使用してブロッキングモードに戻します。ただし、切り替えモードは既存の接続動作に影響する可能性があることに注意することが重要です。
エラー処理:
socket_set_blockを使用する場合、関数の返品値をチェックすることに注意する必要があります。設定が失敗した場合、 socket_last_errorを使用して特定のエラーコードを取得し、それに応じて対応する測定を実行できます。
該当するシナリオ:
ブロッキングモードは通常、クライアントを要求する従来のネットワークモデルなど、順序と整合性を必要とするデータ送信シナリオに適しています。このモードでは、クライアントは次の操作を実行する前にサーバーがデータを返すのを待ちます。
socket_set_blockは、PHPのシンプルで効率的な機能であり、ソケットをブロッキングモードに設定して、プログラムがソケット操作の実行中に操作が完了するのを待つようにします。これは、特定のネットワーク通信シナリオ、特にサーバーが応答して処理するのを待つ必要があるシナリオにとって非常に便利です。実際に、開発者は、ネットワーク通信の効率と安定性を確保するために、独自のニーズに応じてブロッキングモードまたは非ブロッキングモードを選択する必要があります。