1

Unix の世界の inetd と同様に、Perl プログラムから Windows の外部アプリケーションに stdin および stdout として開いている TCP ソケット接続を渡そうとしています。

私が試したこと:

  1. openまたはPOSIX::dup2execを使用して、ソケットで stdin と stdout を「置換」します。

    # $socket is an open TCP socket
    open STDIN,  '<&', $socket or die "Unable to dup stdin: $^E";
    open STDOUT, '>&', $socket or die "Unable to dup stdout: $^E";
    close $socket;
    exec($program) or die "Unable to exec $command: $^E";
    
  2. 使用IPC::open3:

    my $pid = open3(
        '>&'.$socket->fileno, 
        '<&'.$socket->fileno, 
        '<&'.fileno(STDERR), 
        $program);
    waitpid $pid, 0;
    

どちらの場合も、実行されたプログラムはソケットではないもの (おそらくパイプ?) を受け取りますselect。Windows ではselect、ソケットでのみ機能します。

ソケットを外部アプリケーションに渡すにはどうすればよいですか?

ちなみに私は ActiveState ではなく Strawberry Perl を使っています。

4

1 に答える 1

2

残念ながら、Windows では常にこれを実行できるとは限りません。大変な苦労の末、私たちはこれを達成することを断念しました。説明については、この質問 ( TCP SOCKET ハンドルは継承可能ですか? ) を参照してください。

標準の Windows インストールで可能です。TCP ソケットが重複しないように作成されていることを確認する必要があります。これは、WinSock 関数のデフォルトではありません。次に、継承可能としてマークし、子プロセスの stdin/stdout として設定できます。

ただし、特定のよく知られているセキュリティ製品 (ファイアウォール、AV) がインストールされていると、TCP ソケットが適切に継承されないように TCP スタックをフックするため、これを行うことはできません。

本当に安全に継承できるのは、Windows パイプ、ファイル ハンドルなどだけです。子にソケットを与えるには、標準入力として愚かに受け取るのではなく、親と協力する必要があります。親は子を起動しWSADuplicateSocket、ソケットを子の PID に渡すために使用し、ソケットに関するデータを子に (おそらく名前付きパイプを介して子の stdin に) 渡すことができます。次に、子は渡されたデータを使用してソケットを再構成します。そのため、クライアントを再プログラムして、その親を認識できるようにする場合は、それを行うことができます。

Perl でこれを行う方法はわかりませんが、スターターとしてこの興味深い例を参照してください。ネイティブ関数をインポートWSADuplicateSocketして自分でやる必要があると思います。

于 2013-03-14T10:50:16.737 に答える