douyanzhou1450 2019-01-17 21:45
浏览 92
已采纳

通过套接字连接发送GUI / TUI

Recently I have been trying to create a program in golang, which runs on a server, and accepts telnet connections. I would then like to open a TUI (text user interface) such as a curses menu (in the case of golang, something like: termui, gocui, etc) over that telnet connection. My question is, how exactly could I do this and/or would it even be possible? I have played around trying to start TUIs when a connection is accepted, but it just opens it on the server side, not on the telnet client side. From what I can tell, there is no easy way to just send a TUI over a telnet or any other socket IO connection for that matter.

Any help is appreciated in trying to figure this out. Thanks! :D

  • 写回答

1条回答 默认 最新

  • dsa1234569 2019-01-18 01:41
    关注

    First, you should note that the example I give is completely insecure (don't expose it over the Internet!) and also doesn't provide for things like signal handling or resizing of the terminal (you may want to consider using SSH instead).

    But to answer your question, here is an example of running a TCP server and connecting remote clients to a termui program running in a local PTY (uses both the https://github.com/gizak/termui and https://github.com/kr/pty packages):

    package main
    
    import (
        "flag"
        "io"
        "log"
        "net"
        "os"
        "os/exec"
    
        ui "github.com/gizak/termui"
        "github.com/kr/pty"
    )
    
    var termuiFlag = flag.Bool("termui", false, "run a termui example")
    
    func main() {
        flag.Parse()
    
        var err error
        if *termuiFlag {
            err = runTermui()
        } else {
            err = runServer()
        }
        if err != nil {
            log.Fatal(err)
        }
    }
    
    // runTermui runs the termui "Hello World" example.
    func runTermui() error {
        if err := ui.Init(); err != nil {
            return err
        }
        defer ui.Close()
    
        p := ui.NewParagraph("Hello World!")
        p.Width = 25
        p.Height = 5
        ui.Render(p)
    
        for e := range ui.PollEvents() {
            if e.Type == ui.KeyboardEvent {
                break
            }
        }
    
        return nil
    }
    
    // runServer listens for TCP connections on a random port and connects
    // remote clients to a local PTY running the termui example.
    func runServer() error {
        ln, err := net.Listen("tcp", "127.0.0.1:0")
        if err != nil {
            return err
        }
        defer ln.Close()
        log.Printf("Listening for requests on %v", ln.Addr())
        for {
            conn, err := ln.Accept()
            if err != nil {
                return err
            }
            log.Printf("Connecting remote client %v to termui", conn.RemoteAddr())
            go connectTermui(conn)
        }
    }
    
    // connectTermui connects a client connection to a termui process running in a
    // PTY.
    func connectTermui(conn net.Conn) {
        defer func() {
            log.Printf("Closing remote client %v", conn.RemoteAddr())
            conn.Close()
        }()
    
        t, err := pty.StartWithSize(
            exec.Command(os.Args[0], "--termui"),
            &pty.Winsize{Cols: 80, Rows: 24},
        )
        if err != nil {
            log.Printf("Error starting termui: %v", err)
            return
        }
        defer t.Close()
    
        go io.Copy(t, conn)
        io.Copy(conn, t)
    }
    

    Example usage is to run this program in one window and connect to it using nc in another:

    $ go run server.go
    2019/01/18 01:39:37 Listening for requests on 127.0.0.1:56192
    
    $ nc 127.0.0.1 56192
    

    You should see the "Hello world" box (hit enter to disconnect).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用C#,asp.net读取Excel文件并保存到Oracle数据库
  • ¥15 C# datagridview 单元格显示进度及值
  • ¥15 thinkphp6配合social login单点登录问题
  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配