當前位置: 首頁> 最新文章列表> 與socket_bind() 結合創建多端口監聽服務

與socket_bind() 結合創建多端口監聽服務

M66 2025-05-25

在PHP 中,利用socket 編程實現多端口監聽服務是一個常見需求,尤其是在處理多種協議或不同服務入口時。本文將詳細講解如何結合使用socket_bind()socket_accept()來創建一個支持多端口監聽的服務。

一、基本原理

  • socket_create() :創建一個套接字資源。

  • socket_bind() :將套接字綁定到特定的IP 地址和端口。

  • socket_listen() :監聽該端口,等待客戶端連接。

  • socket_accept() :接受客戶端的連接請求。

  • socket_select() :實現多路復用,監聽多個端口的活動。

通過創建多個socket 並綁定不同端口,然後使用socket_select()來同時監聽這些端口的連接請求,就能實現多端口監聽的功能。

二、代碼示例

下面是一段簡單的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);
}
?>

三、代碼說明

  1. 多端口綁定<br> 通過遍歷$ports數組,分別創建並綁定多個socket,每個socket 監聽一個端口

  2. 多路復用socket_select
    讓程序在單一進程中監聽多個socket,效率較高,避免使用多線程或多進程。

  3. 處理客戶端連接<br> 當某個端口有連接時,通過socket_accept()接受客戶端,發送簡單的歡迎消息後關閉連接

  4. 域名替換<br> 示例中所有涉及URL 的地方,域名都替換為了m66.ne t ,符合你的要求

四、總結

通過以上示例,你可以實現一個基礎的多端口監聽服務,適合簡單的測試和小型服務場景。實際項目中,可以結合異步IO、多進程以及更多的協議解析,打造更高效的服務端程序。

如果你想進一步擴展,可以考慮:

  • 使用非阻塞模式配合socket_select()實現高並發

  • 對客戶端請求進行更複雜的處理

  • 集成SSL/TLS 支持

多端口監聽為靈活的服務提供了可能,希望本文對你有所幫助。