$IP='192.168.1.1';//WindowsコンピュータのIP
$Port='5900' //VNC で使用されるポート
;
$ServerPort='9999';//Linux Server が外部で使用するポート
$RemoteSocket=false;//VNCのソケットに接続
関数 SignalFunction($Signal){
//これはメインプロセスのメッセージ処理関数です
global $PID;//子プロセスのPID
スイッチ ($Signal)
{
ケースサイントラップ:
ケースシグターム:
//プログラムを終了するシグナルを受信します
if($PID)
{
// SIGTERM シグナルを Child に送信して、できるだけ早く終了するように伝えます
posix_kill($PID,SIGTERM);
//ゾンビを避けるために子プロセスが終了するまで待ちます
pcntl_wait($Status);
}
//メインプロセスによって開かれたソケットを閉じます
DestroySocket();
exit(0); //メインプロセスを終了します
休憩;
ケース SIGCHLD:
/*
子プロセスが終了すると、子は親に SIGCHLD シグナルを送信します
親が SIGCHLD を受け取ると、子プロセスが終了し、何かを行う時期が来たことがわかります
終了アクション*/
unset($PID); //子プロセスが終了したことを示すために $PID をクリアします
pcntl_wait($Status); //ゾンビを避ける
休憩;
デフォルト:
}
}
関数 ChildSignalFunction($Signal){
//子プロセスのメッセージ処理関数です
スイッチ ($Signal)
{
ケースサイントラップ:
ケースシグターム:
//子プロセスは終了メッセージを受信します
DestroySocket(); //ソケットを閉じる
exit(0); //子プロセスを終了します
デフォルト:
}
}
関数 ProcessSocket($ConnectedServerSocket){
//子プロセスソケット処理関数
//$ConnectedServerSocket -> 外部接続ソケット
グローバル $ServerSocket,$RemoteSocket,$IP,$Port;
$ServerSocket=$ConnectedServerSocket;
declare(ticks = 1); //この行を追加する必要があります。追加しないと、メッセージ処理関数を設定できません。
//メッセージ処理関数を設定します
if(!pcntl_signal(SIGTERM, "ChildSignalFunction")) return;
if(!pcntl_signal(SIGTRAP, "ChildSignalFunction")) return;
//VNCに接続するソケットを作成
$RemoteSocket=socket_create(AF_INET, SOCK_STREAM,SOL_TCP);
// 内部 VNC に接続します
@$RemoteConnected=socket_connect($RemoteSocket,$IP,$Port);
if(!$RemoteConnected) return; //VNC に接続できません End
//プログラムがブロックされないようにソケット処理をノンブロックに設定します
if(!socket_set_nonblock($RemoteSocket)) return;
if(!socket_set_nonblock($ServerSocket)) return;
その間(本当)
{
//ここではプーリングを使用してデータを取得します
$NoRecvData=false; //この変数は、外部接続がデータを読み取ったかどうかを判断するために使用されます
$NoRemoteRecvData=false;//この変数は、VNC 接続がデータを読み取ったかどうかを判断するために使用されます
@$RecvData=socket_read($ServerSocket,4096,PHP_BINARY_READ);
//外部接続から 4096 バイトのデータを読み取ります
@$RemoteRecvData=socket_read($RemoteSocket,4096,PHP_BINARY_READ);
//vnc 接続から 4096 バイトのデータを読み取ります
if($RemoteRecvData==='')
{
//VNC 接続が中断されたため、終了する時間になりました
echo"リモート接続が閉じられました";
戻る
}
if($RemoteRecvData===false)
{
/*
ノンブロックモードを使用しているので
ここでの状況は、vnc 接続に読み取るデータがないということです
*/
$NoRemoteRecvData=true;
//最後のエラーをクリア
socket_clear_error($RemoteSocket);
}
if($RecvData==='')
{
//外部接続が中断されたため、終了する時間になりました
echo "クライアント接続が閉じられました";
戻ります;
}
if($RecvData===false)
{
/*
ノンブロックモードを使用しているので
ここでの状況は、外部接続に読み取るデータがないということです
*/
$NoRecvData=true;
//最後のエラーをクリア
socket_clear_error($ServerSocket);
}
if($NoRecvData&&$NoRemoteRecvData)
{
//外部接続、VNC接続で読み込むデータがない場合
//CPU リソースの長期使用を避けるために、プログラムを 0.1 秒間スリープさせます
usleep(100000);
//目覚めた後、ソケットを読み取るためのプーリングアクションを続行します
続けます;
}
//データを受信
if(!$NoRecvData)
{
//外部接続がデータを読み取ります
その間(本当)
{
//外部接続から読み取ったデータをVNC接続に転送します
@$WriteLen=socket_write($RemoteSocket,$RecvData);
if($WriteLen===false)
{
//ネットワーク伝送の問題により、現在データを書き込むことができません
//0.1 秒間スリープしてから再試行します。
usleep(100000);
続けます;
}
if($WriteLen===0)
{
//リモート接続が中断されたため、プログラムを終了する必要があります
echo"リモート書き込み接続が閉じられました";
戻ります;
}
//外部接続から読み取られたデータが VNC 接続に完全に送信されると、このループは中断されます。
if($WriteLen==strlen($RecvData)) ブレーク;
//データを一度に送信できない場合は、すべてのデータが送信されるまで複数の送信に分割する必要があります
$RecvData=substr($RecvData,$WriteLen);
}
}
if(!$NoRemoteRecvData)
{
//これは、VNC 接続から読み取られ、外部接続に戻されたデータです
//原理は上記とほぼ同じなので詳細は割愛します
その間(本当)
{
@$WriteLen=socket_write($ServerSocket,$RemoteRecvData);
if($WriteLen===false)
{
usleep(100000);
続けます;
}
if($WriteLen===0)
{
echo"リモート書き込み接続が閉じられました";
戻ります;
}
if($WriteLen==strlen($RemoteRecvData)) ブレーク;
$RemoteRecvData=substr($RemoteRecvData,$WriteLen);
}
}
}
}
関数 DestroySocket(){
// 開いた Socket を閉じるために使用されます
グローバル$ServerSocket,$RemoteSocket;
if($RemoteSocket)
{
//VNC 接続が既に有効になっている場合
//ソケットを閉じる前にソケットをシャットダウンする必要があります。そうしないと、接続が閉じられたことが相手に伝わりません
@socket_shutdown($RemoteSocket,2);
socket_clear_error($RemoteSocket);
//ソケットを閉じる
ソケットクローズ($RemoteSocket);
}
// 外部接続を閉じます
@socket_shutdown($ServerSocket,2);
socket_clear_error($ServerSocket);
ソケット_クローズ($ServerSocket);
}
//これがプログラム全体の始まりで、ここからプログラムの実行が始まります
//まずここでフォークを実行します
$PID=pcntl_fork();
if($PID==-1) die("フォークできませんでした");
//$PID が 0 でない場合、これは親プロセスであることを意味します
//$PID は子プロセスです
//これは親プロセスです。自分で終了し、子をデーモンにします。
if($PID) die("デーモン PID:$PIDn");
//ここからデーモンモードが実行されます
//現在のプロセスをターミナルから切り離し、デーモンモードに入ります
if(!posix_setsid()) die("ターミナルから切り離せませんでした");
//デーモンのメッセージ処理関数を設定します
宣言(ティック = 1);
if(!pcntl_signal(SIGTERM, "SignalFunction")) die("エラー!!!n");
if(!pcntl_signal(SIGTRAP, "SignalFunction")) die("Error!!!n");
if(!pcntl_signal(SIGCHLD, "SignalFunction")) die("エラー!!!n");
//外部接続用のソケットを確立します
$ServerSocket=socket_create(AF_INET, SOCK_STREAM,SOL_TCP);
// 外部接続監視用の IP とポートを設定します。IP フィールドを 0 に設定して、すべてのインターフェイス IP がリッスンされていることを示します
if(!socket_bind($ServerSocket,0,$ServerPort)) die("ソケットをバインドできません!n");
//Port のリスニングを開始します
if(!socket_listen($ServerSocket)) die("聴けない!n");
//ソケットをノンブロックモードに設定します
if(!socket_set_nonblock($ServerSocket)) die("サーバーソケットをブロックに設定できません!n");
// 現在子プロセスが存在しないことを示す $PID 変数をクリアします
設定を解除($PID);
その間(本当)
{
//プーリングモードに入り、1秒ごとに接続があるかどうかを確認します。
睡眠(1);
// 接続が入っているかどうかを確認します
@$ConnectedServerSocket=socket_accept($ServerSocket);
if($ConnectedServerSocket!==false)
{
//誰かが入ってきた
// 接続を処理するために子プロセスを開始します
$PID=pcntl_fork();
if($PID==-1) die("フォークできませんでした");
if($PID) continue;//これはデーモン プロセスです。監視を続けます。
//ここから子プロセスが始まります
//Socketで関数を実行
プロセスソケット($ConnectedServerSocket);
//Socket の処理後、Socket を終了します
DestroySocket();
//子プロセスを終了します
終了(0);
}
}
この記事で説明した内容が皆様の PHP プログラミング設計に役立つことを願っています。
http://www.bkjia.com/PHPjc/963999.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/963999.html技術記事 PHP で複数のプロセスを起動する方法 この記事では、PHP で複数のプロセスを起動する方法について説明します。皆さんの参考に共有してください。具体的な実装方法は以下の通りです コードは以下の通りです: ?php $IP='192.168.1.1';//W...