在 Windows 上的 Go 中通过 telnet/ssh 写入现有的 tcp 套接字

发布于 2025-01-10 12:45:07 字数 776 浏览 0 评论 0原文

我正在尝试从另一个控制台/终端应用程序启动的 Go 程序将文本写入/打印到屏幕上 - 一个从老式公告板系统 (BBS) 启动的“门”程序。

BBS 本身通过 telnet 连接运行,localhost:2323。当启动我的程序时,BBS 会自动添加正确的套接字句柄作为参数,然后我可以使用 Flag 读取该句柄(它是一个整数,例如 236)。

显然,在 Linux 中,我只需使用 os.Stdout 来使用 fmt.Println("Hello World!")...但在 Windows 上,我需要以某种方式将 Go 程序的输出通过管道传输/重定向到提供的插座。

这是我开始的函数:

func writeOut(fd int, buf []byte) bool {
    for len(buf) > 0 {
        n, err := syscall.Write(syscall.Handle(fd), buf)
        if err != nil {
            fmt.Println(err)
            return false
        }
        buf = buf[n:]
    }
    return true
}

调用自:

 writeOut(socketInt, []byte("Writing to Windows socket..."))

返回的错误是: 参数不正确

我做错了什么,在 Go 中如何实现?

I am attempting to write/print text to the screen from a Go program launched from another console/terminal application--a "door" program that launches from an old-school Bulletin Board System (BBS).

The BBS itself runs over a telnet connection, localhost:2323. And when launching my program, the BBS automatically adds the correct socket handle as an argument, which I can then read using Flag (it's an integer, like 236).

Obviously, in Linux, I'd just use fmt.Println("Hello World!") using os.Stdout... But on Windows, I need to somehow pipe/redirect the Go program's output to the provided socket.

Here's the function I started with:

func writeOut(fd int, buf []byte) bool {
    for len(buf) > 0 {
        n, err := syscall.Write(syscall.Handle(fd), buf)
        if err != nil {
            fmt.Println(err)
            return false
        }
        buf = buf[n:]
    }
    return true
}

called from:

 writeOut(socketInt, []byte("Writing to Windows socket..."))

The error returned is: The parameter is incorrect

What am I doing wrong, and how would this be accomplished in Go?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

筱武穆 2025-01-17 12:45:07

您不能随意将文件或套接字句柄传递给最初没有从您的进程继承它们的另一个进程。每个进程都有自己独特的一组句柄。在 POSIX 中,继承套接字句柄是可能的(尽管不推荐),但在 Windows 中,它们根本无法被继承(请参阅 TCP SOCKET 句柄可以继承吗?)。

您可以重定向 stdout到TCP不过,在调用 CreateProcess 时,您的程序确实可以将 fmt.Println 发送到 stdout,并且输出将直接发送到套接字:

func serveDoor(conn *net.TCPConn, name string, args ...string) {
    defer conn.Close()

    cmd := exec.Command(name, args...)
    cmd.Stdin = conn
    cmd.Stdout = conn
    cmd.Stderr = conn

    err := cmd.Run()
    fmt.Println("door finished:", err)
}

完整要点

另一种解决方案是使用管道并将其泵送到套接字。

You can't arbitrarily pass file or socket handles to another process that isn't inheriting them from your process in the first place. Each process has its own unique set of handles. In POSIX inheriting socket handles is possible (albeit not recommended) but in Windows they simply cannot be inherited (see Are TCP SOCKET handles inheritable?).

You can redirect stdout to a TCP socket when calling CreateProcess though, so that when invoked, your program can indeed fmt.Println to stdout and the output would go straight to the socket:

func serveDoor(conn *net.TCPConn, name string, args ...string) {
    defer conn.Close()

    cmd := exec.Command(name, args...)
    cmd.Stdin = conn
    cmd.Stdout = conn
    cmd.Stderr = conn

    err := cmd.Run()
    fmt.Println("door finished:", err)
}

(full gist)

Another solution is to use a pipe and pump it to the socket.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文