PHPでは、ネットワーク通信のためにソケットを使用するときに接続を閉じる多くの方法があります。その中で、 Stream_Socket_Shutdown関数は一般的な方法であり、開発者がソケットのシャットダウンプロセスをより詳細に制御できるようになります。 stream_socket_shutdownとその適用可能なシナリオの役割を理解することは、コードの堅牢性とパフォーマンスを改善するために重要です。
Stream_Socket_shutdownは、ソケット接続を閉じるためにPHPで使用される方法です。 Simple fclose()またはsocket_close()とは異なり、より多くの制御オプションを提供し、開発者が読み取り操作を閉じるか、接続を完全に閉じるかを選択できるようにします。関数プロトタイプは次のとおりです。
<span><span><span class="hljs-keyword">bool</span></span><span> </span><span><span class="hljs-title function_ invoke__">stream_socket_shutdown</span></span><span>(resource </span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-variable">$how</span></span><span>);
</span></span>
$ socket :閉じるソケットリソースを表します。
$ How :閉じられている操作の種類を制御します。次のことができます。
stream_shut_rd :読み取り操作をオフにして、書き込み機能を保持します。
stream_shut_wr :書き込み操作をオフにし、読み取り関数を維持します。
Stream_shut_rdwr :読み取りおよび書き込み操作を同時に閉じ、接続を完全に閉じます。
いくつかのアプリケーションシナリオでは、クライアントまたはサーバーはデータを送信した後に記述する必要はありませんが、相手が応答するのを待つだけです。たとえば、HTTP要求が完了した後、クライアントはデータを送信しなくなりますが、サーバーが応答を返すのを待つだけです。現時点では、 stream_socket_shutdownを使用して、書き込み操作を閉じ、リソースの消費を削減し、パフォーマンスを向上させることができます。
サンプルコード:
<span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_socket_client</span></span><span>(</span><span><span class="hljs-string">"tcp://example.com:80"</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-string">"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"</span></span><span>);
</span><span><span class="hljs-comment">// リクエストを送信した後、書き込み操作を閉じます,これ以上のデータは送信されません</span></span><span>
</span><span><span class="hljs-title function_ invoke__">stream_socket_shutdown</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, STREAM_SHUT_WR);
</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__">fread</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-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span></span>
この例では、クライアントはHTTPリクエストを送信しており、サーバーにデータを書き込む必要がなくなったため、 Stream_Socket_shutdownを呼び出すことで書き込み操作が閉じられます。
一部のアプリケーションでは、クライアントまたはサーバーは、相手からデータを読み取るだけで、データを送信する必要がある場合があります。この時点で、 Stream_Socket_Shock_shutdownを使用して書き込み操作を閉じて、接続が不要な書き込みリソースを消費しなくなったことを確認できます。たとえば、FTPプロトコルの一部のモードでは、クライアントとサーバーが作成せずにデータを読み取るだけです。
サンプルコード:
<span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_socket_client</span></span><span>(</span><span><span class="hljs-string">"tcp://example.com:21"</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-string">"USER anonymous\r\n"</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-string">"PASS anonymous\r\n"</span></span><span>);
</span><span><span class="hljs-comment">// これ以上のデータは送信されません,書き込み操作を閉じます</span></span><span>
</span><span><span class="hljs-title function_ invoke__">stream_socket_shutdown</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, STREAM_SHUT_WR);
</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__">fread</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-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span></span>
書き込み操作をオフにすることにより、不必要なリソースの使用を削減し、通信プロセスをより効率的に保証できます。
ライブチャットシステムやオンラインゲームなどの双方向通信を必要とする一部のアプリケーションでは、通常、クライアントまたはサーバー側のデータ交換を完了した後、 Stream_Socket_Shutdownに電話して、接続を完全に閉じて関連するすべてのリソースをリリースします。 Stream_shut_rdwrを使用して接続を閉じ、読み取り操作と書き込み操作の両方が適切に終了するようにします。
サンプルコード:
<span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_socket_client</span></span><span>(</span><span><span class="hljs-string">"tcp://example.com:12345"</span></span><span>);
</span><span><span class="hljs-comment">// 双方向のデータ交換を実施します</span></span><span>
</span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-string">"Hello Server!"</span></span><span>);
</span><span><span class="hljs-variable">$response</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fread</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-comment">// 双方向通信を完了した後、接続を完全に閉じます</span></span><span>
</span><span><span class="hljs-title function_ invoke__">stream_socket_shutdown</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, STREAM_SHUT_RDWR);
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span></span>
現時点では、両当事者はコミュニケーションを継続する必要がなくなりました。 Stream_Socket_shutdownを呼び出して、読み取りおよび書き込み操作を閉じて、ソケット接続が完全に閉じられていることを確認します。
特別な場合には、異常な中断またはエラーのためにネットワーク接続が閉じられる場合があります。 Stream_Socket_shutdownを使用して、ソケットのシャットダウンプロセスをより詳細に制御します。たとえば、ネットワークの中断またはアプリケーションの例外が発生した場合、読み取りまたは書き込み操作をオプションでオフにして、継続的なリソースの占有を防ぐことができます。
サンプルコード:
<span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_socket_client</span></span><span>(</span><span><span class="hljs-string">"tcp://example.com:80"</span></span><span>);
</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-keyword">die</span></span><span>(</span><span><span class="hljs-string">"Unable to connect to server"</span></span><span>);
}
</span><span><span class="hljs-comment">// いくつかのエラーが発生すると仮定します,データの書き込みを停止します</span></span><span>
</span><span><span class="hljs-title function_ invoke__">stream_socket_shutdown</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, STREAM_SHUT_WR);
</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__">fread</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-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span></span>
ここで、例外またはエラーが発生した場合、書き込み操作を閉じることにより、サーバーへの影響を軽減するためにデータを書き込む試みを避けます。
一部のアプリケーションは、タイムアウトメカニズムを実装する必要がある場合があります。つまり、接続が長い間応答していないときにソケット接続を積極的に閉じます。この場合、 Stream_Socket_Shutdownを使用して、不要になった接続を閉じるために使用できます。そのため、デッドロックやネットワークリソースの長期的な占有を待つことは避けられます。
サンプルコード:
<span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_socket_client</span></span><span>(</span><span><span class="hljs-string">"tcp://example.com:80"</span></span><span>, </span><span><span class="hljs-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-number">30</span></span><span>);
</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-keyword">die</span></span><span>(</span><span><span class="hljs-string">"Unable to connect: <span class="hljs-subst">$errstr</span></span></span><span> (</span><span><span class="hljs-subst">$errno</span></span><span>)");
}
</span><span><span class="hljs-comment">// タイムアウトメカニズムを設定します,タイムアウト後に接続を閉じます</span></span><span>
</span><span><span class="hljs-title function_ invoke__">stream_set_timeout</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-number">10</span></span><span>); </span><span><span class="hljs-comment">// タイムアウト時間を設定します102番</span></span><span>
</span><span><span class="hljs-variable">$response</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fread</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">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">feof</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">"Connection timed out or completed.\n"</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">stream_socket_shutdown</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, STREAM_SHUT_RDWR);
}
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span></span>
この例では、接続が10秒以内に応答しない場合、 stream_socket_shutdownが呼び出され、接続を閉じます。
Stream_Socket_shutdownは、ソケット接続の閉鎖をきめんった制御を提供するPHPの非常に有用な機能です。片道通信中の書き込み操作の閉鎖、双方向通信後の接続を閉じる、ネットワークの例外処理など、さまざまなシナリオに適しています。使用方法を理解することで、開発者がネットワークリソースをより効果的に管理し、アプリケーションの安定性とパフォーマンスを改善するのに役立ちます。