Windows 下重定向当前进程的 stdout 到网络连接
这篇讲的是在 Windows 系统下,如何将一个正在运行的进程的标准输出(stdout)重定向到一个 TCP 网络连接中。这并非一个简单的 API 调用,作者为了解决这个需求,深入探索了 Windows 与 POSIX 在底层 I/O 机制上的根本差异。 作者指出,尽管 Windows 提供了 `_dup2` 来模拟 POSIX 的 `dup2`,但其进程标准输出句柄(HANDLE)与 C 运行时的文件描述符(fd)之间的绑定关系是静态的。在进程运行时调用 `SetStdHandle` 并无法影响 `cout` 或 `printf` 的输出流,这是解决问题的第一个关键障碍。 更麻烦的是,Windows 下的 socket 不能直接作为普通的文件句柄使用,因此无法通过 `dup2` 直接传递。作者最终采用的核心方案是:先用 `dup2` 将 stdout 重定向到一个匿名管道,然后启动一个独立的转发线程,持续从该管道读取数据并发送到目标网络连接中。这个方案还巧妙地解决了进程结束时可能丢失末尾输出的问题——通过主动关闭管道来通知转发线程结束,确保数据完整性。 整个探索过程涉及了 Windows 内核对象、句柄复制、管道 I/O 与多线程同步等多个层面的考量,最终作者将实现封装成了一个 Lua 模块,并在 GitHub 上提供了可运行的示例代码。