現在の位置: ホーム> 最新記事一覧> socket_selectを使用して、複数のソケットが読み取り可能かどうかを確認する方法は? PHP実用的なヒント説明

socket_selectを使用して、複数のソケットが読み取り可能かどうかを確認する方法は? PHP実用的なヒント説明

gitbox 2025-09-12
<span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-comment">// このドキュメントは、教育目的のためのものです,方法を示します PHP で使用されます socket_select 複数を確認してください Socket 読みやすいですか。</span></span><span>
</span><span><span class="hljs-comment">// 有効になっていることを確認してください sockets 拡張。</span></span><span>

</span><span><span class="hljs-comment">// 例を作成します sockets(サーバ socket そしていくつかのクライアント socket),コアロジックに集中するために、作成プロセスを省略します。</span></span><span>

</span><span><span class="hljs-comment">// -------------------------------</span></span><span>

</span><span><span class="hljs-meta">?&gt;</span></span><span>

</span><span><span class="hljs-comment"># それを使用する方法 socket_select 複数を確認してください Socket 読みやすいですか?PHP 実践的なスキルの説明</span></span><span>

ネットワークベースのコミュニケーションの開発 PHP 適用するとき,多くの場合、複数の接続を同時に処理する必要があります,特にチャットルームを建設するとき、游戏サーバ或即时通信系统等场景中。現時点では,`</span><span><span class="hljs-title function_ invoke__">socket_select</span></span><span>()` 機能は特に重要です。それはあなたが複数に行くことを可能にします socket 非ブロッキング読み取りワイトチェックは間に実行されます,効率を大幅に向上させます。

この記事では、使用方法を詳細に理解してください `socket_select` 複数を確認してください socket 読みやすいですか,シンプルで実用的な例を示します。

</span><span><span class="hljs-comment">## 何ですか socket_select?</span></span><span>

`</span><span><span class="hljs-title function_ invoke__">socket_select</span></span><span>()` はい PHP 底に `</span><span><span class="hljs-title function_ invoke__">select</span></span><span>()` システムコールのカプセル化。一連のセットを検出するために使用されます sockets はい否可以进行读、書き込みまたは例外操作,タイムアウトを設定できます。

```php
</span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-title function_ invoke__">socket_select</span></span><span>(</span><span><span class="hljs-keyword">array</span></span><span> &amp;</span><span><span class="hljs-variable">$read</span></span><span>, </span><span><span class="hljs-keyword">array</span></span><span> &amp;</span><span><span class="hljs-variable">$write</span></span><span>, </span><span><span class="hljs-keyword">array</span></span><span> &amp;</span><span><span class="hljs-variable">$except</span></span><span>, </span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-variable">$tv_sec</span></span><span>, </span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-variable">$tv_usec</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>)
</span></span>
  • $ read :読みやすいかどうかを監視するソケット。

  • $ write :ソケット(nullに合格できるかどうか)を監視する必要があります。

  • $を除き:例外ソケットがあるかどうかを監視する必要があります(nullに合格することができます)。

  • $ TV_SECおよび$ TV_USEC :それぞれ秒のタイムアウト時間とマイクロ秒です。

実用的な例:複数のソケットに読むデータがあるかどうかを確認してください

複数のクライアントソケットにデータが到着したかどうかをチェックするSocket_Selectを実際に使用するPHPコードスニペットがあります。

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-comment">// 创建主サーバ socket</span></span><span>
</span><span><span class="hljs-variable">$server</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-title function_ invoke__">socket_bind</span></span><span>(</span><span><span class="hljs-variable">$server</span></span><span>, </span><span><span class="hljs-string">'127.0.0.1'</span></span><span>, </span><span><span class="hljs-number">8888</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">socket_listen</span></span><span>(</span><span><span class="hljs-variable">$server</span></span><span>);

</span><span><span class="hljs-comment">// 非ブロッキングを設定します</span></span><span>
</span><span><span class="hljs-title function_ invoke__">socket_set_nonblock</span></span><span>(</span><span><span class="hljs-variable">$server</span></span><span>);

</span><span><span class="hljs-variable">$clients</span></span><span> = [</span><span><span class="hljs-variable">$server</span></span><span>];

</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-literal">true</span></span><span>) {
    </span><span><span class="hljs-variable">$readSockets</span></span><span> = </span><span><span class="hljs-variable">$clients</span></span><span>;
    </span><span><span class="hljs-variable">$writeSockets</span></span><span> = </span><span><span class="hljs-literal">null</span></span><span>;
    </span><span><span class="hljs-variable">$exceptSockets</span></span><span> = </span><span><span class="hljs-literal">null</span></span><span>;

    </span><span><span class="hljs-comment">// どのものがチェックされていますか socket 読みやすい(ブロックなし,1 2番目のタイムアウト)</span></span><span>
    </span><span><span class="hljs-variable">$numChangedSockets</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_select</span></span><span>(</span><span><span class="hljs-variable">$readSockets</span></span><span>, </span><span><span class="hljs-variable">$writeSockets</span></span><span>, </span><span><span class="hljs-variable">$exceptSockets</span></span><span>, </span><span><span class="hljs-number">1</span></span><span>);

    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$numChangedSockets</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_select 失敗:"</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>()) . PHP_EOL;
        </span><span><span class="hljs-keyword">break</span></span><span>;
    }

    </span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$readSockets</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$sock</span></span><span>) {
        </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$sock</span></span><span> === </span><span><span class="hljs-variable">$server</span></span><span>) {
            </span><span><span class="hljs-comment">// 新しい接続があります</span></span><span>
            </span><span><span class="hljs-variable">$newClient</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_accept</span></span><span>(</span><span><span class="hljs-variable">$server</span></span><span>);
            </span><span><span class="hljs-title function_ invoke__">socket_set_nonblock</span></span><span>(</span><span><span class="hljs-variable">$newClient</span></span><span>);
            </span><span><span class="hljs-variable">$clients</span></span><span>[] = </span><span><span class="hljs-variable">$newClient</span></span><span>;
            </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"新しいクライアントが接続されています。"</span></span><span> . PHP_EOL;
        } </span><span><span class="hljs-keyword">else</span></span><span> {
            </span><span><span class="hljs-comment">// クライアントがデータを送信します</span></span><span>
            </span><span><span class="hljs-variable">$data</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">socket_read</span></span><span>(</span><span><span class="hljs-variable">$sock</span></span><span>, </span><span><span class="hljs-number">1024</span></span><span>, PHP_NORMAL_READ);
            </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$data</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span> || </span><span><span class="hljs-variable">$data</span></span><span> === </span><span><span class="hljs-string">""</span></span><span>) {
                </span><span><span class="hljs-comment">// クライアントの切断</span></span><span>
                </span><span><span class="hljs-variable">$index</span></span><span> = </span><span><span class="hljs-title function_ invoke__">array_search</span></span><span>(</span><span><span class="hljs-variable">$sock</span></span><span>, </span><span><span class="hljs-variable">$clients</span></span><span>);
                </span><span><span class="hljs-keyword">unset</span></span><span>(</span><span><span class="hljs-variable">$clients</span></span><span>[</span><span><span class="hljs-variable">$index</span></span><span>]);
                </span><span><span class="hljs-title function_ invoke__">socket_close</span></span><span>(</span><span><span class="hljs-variable">$sock</span></span><span>);
                </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"クライアントの切断。"</span></span><span> . PHP_EOL;
            } </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">"受信したデータ:"</span></span><span> . </span><span><span class="hljs-title function_ invoke__">trim</span></span><span>(</span><span><span class="hljs-variable">$data</span></span><span>) . PHP_EOL;
            }
        }
    }
}
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

キーポイントの概要

  1. ノンブロッキングソケット:メインプロセスのブロックを避けるには、すべてのソケットを非ブロッキングモードに設定する必要があります。

  2. メインソケットチェック接続リクエストsocket_selectがメインソケットが読み取り可能であることを検出した場合、新しいクライアント接続要求があることを示します。

  3. クライアントソケットチェックデータ:クライアントソケットが読み取り可能な場合、クライアントがデータを送信したことを意味します。

  4. :読み取りが失敗するか、空の文字列が返された場合、クライアントは切断されたと見なされる必要があります。

結論

Socket_Select()は、同時ソケット通信を処理するための重要なツールです。各接続にスレッドまたはプロセスがあるという事実と比較して、選択モデルは、より軽量で制御可能な多数の接続を管理できます。熟練していると、PHPネットワークアプリケーションがより安定して効率的になります。

この記事が、 socket_selectの使用シナリオとプラクティスを理解し、プロジェクトで本当に役割を果たすことができることを願っています。

 <span></span>