windows - 如何将打开的 TCP 套接字作为标准输入和标准输出从 Perl 传递到 Windows 应用程序

标签 windows perl sockets strawberry-perl

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

我尝试过的:

  1. 使用 openPOSIX::dup2 并调用 exec 将 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 仅适用于套接字。

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

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

最佳答案

遗憾的是,在 Windows 上您不能总是这样做。在经历了巨大的痛苦之后,我们放弃了能够实现这一目标。请参阅此问题 ( Are TCP SOCKET handles inheritable?) 以获取解释。

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

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

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

我不确定如何在 Perl 上完成此操作,但请参阅 this interesting example首先。我想,您必须导入 native WSADuplicateSocket 函数并自行完成。

关于windows - 如何将打开的 TCP 套接字作为标准输入和标准输出从 Perl 传递到 Windows 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15406830/

相关文章:

perl - 如何优化这个 Perl 文件查找?

regex - Perl 中除 0 和 1 之外的所有字符的正则表达式

regex - Perl 中为什么需要括号来保存正则表达式的结果?

sockets - 如何处理 go 中的粘性 tcp 数据包?

windows - 为 Windows 创建 R 包

windows - 一台 Windows 服务器上的 IIS 和 TOMCAT

c - 是否有用于发送的 fprintf?

java - 与 Jackson 通过 Socket 进行 Json

c++ - 将控制台应用程序的输出直接输出到 Visual Studio 而不是外部 Windows 控制台

c++ - 如何测量亚秒级持续时间?