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 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看