我正在尝试从golang中的SSH会话读取数据。我编写了以下函数来尝试实现此目的。
我遇到了一个问题,尝试从stdout读取内容,它为空,导致程序锁定。为了解决这个问题,我编写了BufferSocketData,它检查ReadDataFromSocket应该附加到的通道,如果它有数据,则将其添加到缓冲区。如果1秒钟后仍未收到任何数据,它将停止读取。
但是,这不能正常工作,我不确定为什么。即使缓冲区中有数据,也只有第一个读取获得新数据,随后的读取返回空字符串。
在上一个问题中,我能够使用SetReadDeadline限制从套接字读取的时间,是否可以在SSH会话中使用类似的功能?还是我需要一起使用其他策略?
/* ReadDataFromSocket - Attempts to read any data in the socket. */ func ReadDataFromSocket(sock io.Reader, c chan string) { var recvData = make([]byte, 1024) var numBytes, _ = sock.Read(recvData) c <- string(recvData[:numBytes]) } /* BufferSocketData - Read information from the socket and store it in the buffer. */ func (s *SSHLib) BufferSocketData(inp chan string, out chan string) { var data string var timeout int64 = 1000 // 1 second timeout. var start = utils.GetTimestamp() for utils.GetTimestamp()-start < timeout { select { case data = <-inp: default: } if data != "" { break } } out <- data } /* GetData - Start goroutines to get and buffer data. */ func (s *SSHLib) GetData() { var sockCh = make(chan string) var buffCh = make(chan string) go ReadDataFromSocket(s.Stdout, sockCh) go s.BufferSocketData(sockCh, buffCh) var data = <-buffCh if data != "" { s.Buffer += data } }
如果您需要其他任何信息,请告诉我。
启动会话的单个阅读器goroutine。该goroutine从会话中读取数据并将数据发送到通道。
在主goroutine中,循环选择接收数据和超时情况。适当处理每种情况。
type SSHLib struct { Stdout io.Reader Buffer string Data chan string // <-- Add this member } // New creates a new SSHLib. This example shows the code // relevant to reading stdout only. func New() *SSHLib { s := &SSHLib{Data: make(chan string)} go s.Reader() return s } // Reader reads data from stdout in a loop. func (s *SSHLib) Reader() { var data = make([]byte, 1024) for { n, err := s.Stdout.Read(data) if err != nil { // Handle error return } s.Data <- string(data[:n]) } } // GetData receives data until regexp match or timeout. func (s *SSHLib) GetData() { t := time.NewTimer(time.Second) defer t.Stop() for { select { case d := <-s.Data: s.Buffer += d // Check for regexp match in S.Buffer case <-t.C: // Handle timeout return } } }