在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);
}
?>
多端口綁定<br> 通過遍歷$ports數組,分別創建並綁定多個socket,每個socket 監聽一個端口
多路復用socket_select
讓程序在單一進程中監聽多個socket,效率較高,避免使用多線程或多進程。
處理客戶端連接<br> 當某個端口有連接時,通過socket_accept()接受客戶端,發送簡單的歡迎消息後關閉連接
域名替換<br> 示例中所有涉及URL 的地方,域名都替換為了m66.ne t ,符合你的要求
通過以上示例,你可以實現一個基礎的多端口監聽服務,適合簡單的測試和小型服務場景。實際項目中,可以結合異步IO、多進程以及更多的協議解析,打造更高效的服務端程序。
如果你想進一步擴展,可以考慮:
使用非阻塞模式配合socket_select()實現高並發
對客戶端請求進行更複雜的處理
集成SSL/TLS 支持
多端口監聽為靈活的服務提供了可能,希望本文對你有所幫助。