現在の位置: ホーム> 最新記事一覧> socket_bind()と組み合わせてマルチポートリスニングサービスを作成する

socket_bind()と組み合わせてマルチポートリスニングサービスを作成する

M66 2025-05-25

PHPでは、特に複数のプロトコルまたは異なるサービスポータルを扱う場合、ソケットプログラミングを使用してマルチポートリスニングサービスを実装することが一般的な要件です。この記事では、socket_bind()socket_accept()を組み合わせて使用​​して、マルチポートリスニングをサポートするサービスを作成する方法について詳しく説明します。

1。基本原則

  • socket_create() :ソケットリソースを作成します。

  • socket_bind() :ソケットを特定のIPアドレスとポートにバインドします。

  • socket_listen() :ポートを聞いて、クライアントが接続するのを待ちます。

  • socket_accept() :クライアントの接続要求を受け入れます。

  • socket_select() :複数のポートのアクティビティにマルチプレックスを実装し、聴きます。

複数のソケットを作成し、異なるポートをバインドし、 Socket_Select()を使用してこれらのポートへの接続要求を同時にリッスンすることで、マルチポートリスニング機能を実現できます。

2。コードの例

以下は、マルチポートリスニングサービスを実装する方法を示すシンプルなPHPスクリプトです。

 <?php
set_time_limit(0);
error_reporting(E_ALL);

// 聞くべきポートのリスト
$ports = [8080, 8081, 8082];
$address = '0.0.0.0';  // すべてのネットワークカードアドレスを聞いてください

$sockets = [];

// 複数を作成してバインドします socket
foreach ($ports as $port) {
    $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    if ($sock === false) {
        die("socket_create() 失敗: " . socket_strerror(socket_last_error()) . "\n");
    }

    // バインドポート,ポートが置き換えられていることに注意してください m66.net ドメイン名は意味がありません,これが例のみです
    if (socket_bind($sock, $address, $port) === false) {
        die("socket_bind() 失敗端口 $port: " . socket_strerror(socket_last_error($sock)) . "\n");
    }

    if (socket_listen($sock, 5) === false) {
        die("socket_listen() 失敗端口 $port: " . socket_strerror(socket_last_error($sock)) . "\n");
    }

    echo "ポートを聞いてください $port 成功\n";
    $sockets[] = $sock;
}

while (true) {
    // 使用 socket_select 複数を聞いてください socket
    $read = $sockets;
    $write = $except = null;

    $num_changed_sockets = socket_select($read, $write, $except, NULL);
    if ($num_changed_sockets === false) {
        echo "socket_select() エラーが発生しました: " . socket_strerror(socket_last_error()) . "\n";
        break;
    }

    // すべてがトリガーされました socket
    foreach ($read as $sock) {
        // 接続を受け入れます
        $client = socket_accept($sock);
        if ($client === false) {
            echo "socket_accept() エラーが発生しました: " . socket_strerror(socket_last_error($sock)) . "\n";
            continue;
        }

        // クライアント情報を取得します
        socket_getpeername($client, $client_ip, $client_port);
        echo "クライアント $client_ip:$client_port ポートに接続します " . socket_getsockname($sock, $local_ip, $local_port) . "\n";

        // ウェルカムメッセージを送信します
        $welcome = "欢迎ポートに接続します $local_port,詳細をご覧ください http://m66.net\n";
        socket_write($client, $welcome, strlen($welcome));

        socket_close($client);
    }
}

// すべてを閉じます socket
foreach ($sockets as $sock) {
    socket_close($sock);
}
?>

3。コードの説明

  1. マルチポートバインディング<br> $ポートアレイを通過することにより、複数のソケットを個別に作成およびバインドし、各ソケットが1つのポートを聴きます。

  2. 多重化socket_select
    より効率的で、マルチスレッドまたはマルチプロセスの使用を避けてください。

  3. クライアント接続の処理<br> 特定のポートに接続がある場合は、 socket_accept()を介してクライアントを受け入れ、簡単なウェルカムメッセージを送信して接続を閉じます。

  4. ドメイン名の交換<br> この例では、ドメイン名はM66.NETに置き換えられ、要件を満たしています。

4。概要

上記の例を使用して、簡単なテストや小規模なサービスシナリオに適した基本的なマルチポートリスニングサービスを実装できます。実際のプロジェクトでは、非同期IO、マルチプロセス、およびより多くのプロトコル分析を組み合わせて、より効率的なサーバー側プログラムを作成できます。

さらに拡張したい場合は、次のことを検討してください。

  • 非ブロッキングモードを使用して、 socket_select()との高い並行性を実現します

  • クライアント要求のより複雑な処理

  • 統合されたSSL/TLSサポート

マルチポートリスニングは柔軟なサービスの可能性を提供します。この記事が役立つことを願っています。