PHPを使用してソケットベースのネットワークをプログラミングする場合、接続の確立と切断が2つの重要なステップです。ここで、 socket_accept()はクライアントからの接続を受け入れるために使用され、 socket_shutdown()は接続を閉じるために使用されます。これら2つの機能の適切なペアリングは、通信の安定性とリソースのリリースを確保するために特に重要です。この記事では、正しい使用法と予防策を詳細に調べます。
サーバーがsocket_create()とsocket_bind()を使用してリスニングソケットを作成およびバインドすると、 socket_listen()を介してクライアントリクエストの聴取を開始します。現時点では、 socket_accept()は、着信接続要求を受け入れ、クライアントとの通信に使用される新しいソケットリソースを返す責任があります。
例:
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($server, '0.0.0.0', 8080);
socket_listen($server);
while (true) {
$client = socket_accept($server);
if ($client) {
socket_write($client, "訪問してください m66.net\r\n");
// 後続の通信ロジック
}
}
ここでは、 $クライアントは新しい接続ソケットですが、 $サーバーはリスニングのままです。
Socket_shutdown()は、確立された接続の読み取り、書き込み、および書き込みチャネルを閉じるために使用されます。プロトタイプは次のとおりです。
bool socket_shutdown(resource $socket, int $how = 2);
パラメーター$の値方法:
0 :読み取り側を閉じます
1 :書き込み側を閉じます
2 :読み取りと書き込みをオフにする(デフォルト)
socket_shutdown()を使用して相手に優雅に通知します。接続が閉じようとしているので、「偶発的な切断」のためにクライアントのエラーを避けるために準備してください。
エンド通信:最初に送信されるデータを完成させて、書き込みバッファーがクリアされていることを確認します。
socket_shutdown()を呼び出します:接続を優雅に閉じます。
socket_close()を呼び出します:ソケットリソースをリリースします。
例:
socket_write($client, "さようなら,訪問してくれてありがとう m66.net\r\n");
// 閉じて読んでください
socket_shutdown($client);
// 無料のリソース
socket_close($client);
この注文により、クライアントは、メッセージ伝達中に閉じる代わりに「さようなら」メッセージを受信できるようになります。
エラーの使用量:socket_shutdown()データが書き終えない直後
socket_write($client, "さようなら"); // データはまだバッファにある可能性があります
socket_shutdown($client);
この慣行により、クライアントは完全な情報を受け取らない可能性があります。書き込みが完了したことを確認した後、閉鎖する必要があります。
エラーの使用量:socket_accept()は接続を閉じません
socket_shutdown()およびsocket_close()が呼び出されない場合、ファイル記述子の疲労により長い間実行した後、リソースが漏れてクラッシュします。
一部のシナリオ(同時サーバーなど)では、非ブロッキングモードが使用されます。現時点では、 socket_accept()が正常に戻るかどうかを確認するように注意する必要があります。空の接続でsocket_shutdown()を呼び出して警告を発生させる必要があります。
socket_set_nonblock($server);
$client = @socket_accept($server);
if ($client !== false) {
// コミュニケーションとシャットダウンロジック
}
PHPでsocket_accept()を使用して接続を受信した後、 socket_shutdown()およびsocket_close()と協力してリソースをリリースしてください。 socket_shutdown()の機能は、残酷に切断されるのではなく、優雅に切断し、相手に切断の準備をするように通知することです。この正しいプロセスを習得すると、ソケット通信の堅牢性とユーザーエクスペリエンスが向上します。
実際の開発では、複数のクライアントまたはより複雑なロジックが関与している場合は、 Stream_Socket_Server()などの高次インターフェイスを組み合わせたり、イベント駆動型処理にSelect() / Poll()を使用して、より安定したネットワークサービスを実現することをお勧めします。