首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP fork 與 Socket 實作:打通 VNC 連線的反向代理範例

     編輯:PHP 相關知識

應用場景

家用無線 AP 僅支援將公網 IP 映射到內網 Linux 伺服器,無法針對特定埠做端口轉發。需從外部經由 Linux 伺服器的某個埠,連線到內網 Windows 主機的 VNC 服務(預設埠 5900)。

解決方案:PHP 多程序 Socket 代理

程式在 Linux 伺服器監聽指定埠(如 9999),收到外部連線後,fork 子程序連接內網 VNC 埠,雙向透傳資料封包,實現「外部埠 → Linux → 內網 VNC」的通道。

核心程式碼結構

<?php
$IP = "192.168.1.1";        // Windows 主機 IP
$Port = 5900;               // VNC 埠
$ServerPort = 9999;         // Linux 對外監聽埠
$RemoteSocket = false;      // VNC 連線 Socket

// 訊號處理:父程序捕捉 SIGTERM/SIGTRAP 終止子程序,SIGCHLD 回收僵屍程序
function SignalFunction($Signal) { ... }
function ChildSignalFunction($Signal) { ... }

// 子程序:雙向資料轉發
function ProcessSocket($ConnectedServerSocket) {
    global $ServerSocket, $RemoteSocket, $IP, $Port;
    $ServerSocket = $ConnectedServerSocket;
    $RemoteSocket = socket_create(AF_INET, SOCK_STREAM, 0);
    socket_connect($RemoteSocket, $IP, $Port);
    // 使用 socket_select 同時監聽兩個 Socket,實現雙向透傳
    while (true) {
        $read = array($ServerSocket, $RemoteSocket);
        socket_select($read, $write, $except, NULL);
        foreach ($read as $sock) {
            $data = socket_read($sock, 8192);
            if ($data === false || $data === "") break 2;
            $target = ($sock === $ServerSocket) ? $RemoteSocket : $ServerSocket;
            socket_write($target, $data, strlen($data));
        }
    }
    DestroySocket();
}

// 主程序:建立監聽 Socket,accept 後 fork 子程序處理
$ServerSocket = socket_create(AF_INET, SOCK_STREAM, 0);
socket_bind($ServerSocket, "0.0.0.0", $ServerPort);
socket_listen($ServerPort);
pcntl_signal(SIGTERM, "SignalFunction");
pcntl_signal(SIGCHLD, "SignalFunction");
while (true) {
    $ClientSocket = socket_accept($ServerSocket);
    $pid = pcntl_fork();
    if ($pid == -1) { socket_close($ClientSocket); continue; }
    if ($pid == 0) { // 子程序
        pcntl_signal(SIGTERM, "ChildSignalFunction");
        ProcessSocket($ClientSocket);
        exit(0);
    } else { // 父程序
        $PID = $pid;
        socket_close($ClientSocket);
    }
}
?>

關鍵技術點

  • pcntl_fork() 建立子程序,各自處理獨立連線
  • 訊號機制(pcntl_signal)實現優雅關閉與僵屍程序回收
  • socket_select() 多路複用實現高效雙向資料轉發

此範例展示了 PHP 在系統層面網路程式設計的能力,可擴展為通用的 TCP 端口轉發工具。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved