【问题标题】:How to pass an open TCP socket from Perl to Windows application as stdin and stdout如何将打开的 TCP 套接字从 Perl 传递到 Windows 应用程序作为标准输入和标准输出
【发布时间】:2013-03-02 15:47:21
【问题描述】:

我正在尝试将来自 Perl 程序的开放 TCP 套接字连接作为标准输入和标准输出传递到 Windows 上的外部应用程序,类似于 Unix 世界中的 inetd 所做的。

我尝试过的:

  1. 使用 openPOSIX::dup2 并调用 exec 的套接字“替换”标准输入和标准输出:

    # $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 仅适用于套接字。

如何将套接字传递给外部应用程序?

顺便说一下,我使用的是 Strawberry Perl,而不是 ActiveState。

【问题讨论】:

    标签: windows perl sockets strawberry-perl


    【解决方案1】:

    遗憾的是,在 Windows 上,您不能总是这样做。经过巨大的痛苦,我们放弃了能够做到这一点。请参阅此问题 (Are TCP SOCKET handles inheritable?) 以获得解释。

    在普通的 Windows 安装上是可能的:您必须确保创建的 TCP 套接字不重叠,这不是 WinSock 函数的默认设置。然后可以将其标记为可继承并设置为子进程的标准输入/标准输出。

    但是,如果安装了某些知名的安全产品(防火墙、防病毒),则无法执行此操作,因为它们挂接 TCP 堆栈的方式会阻止 TCP 套接字被正确继承。

    您只能安全地真正继承 Windows 管道、文件句柄等。要给孩子一个套接字,它必须与父母合作,而不是愚蠢地接受它作为标准输入。父母可以启动孩子,使用WSADuplicateSocket 将套接字提供给孩子的PID,将有关套接字的数据传递给孩子(可能通过命名管道传递给孩子的标准输入)。然后,孩子使用传递的数据重构套接字。因此,如果您愿意对客户端进行重新编程以了解其父级,则可以这样做。

    我不确定如何在 Perl 上完成此操作,但请参阅 this interesting example 了解初学者。我想你必须导入本机 WSADuplicateSocket 函数并自己做。

    【讨论】:

    • 谢谢,看来使用WSADuplicateSocket 传递套接字是唯一真正的选择。
    猜你喜欢
    • 2014-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    • 2021-05-18
    相关资源
    最近更新 更多