Чтение данных из сессии SSH Golang - PullRequest
0 голосов
/ 26 июня 2018

Я разместил похожий вопрос здесь для чтения из сеанса telnet.

Я пытаюсь прочитать данные из сеанса SSH в Голанге. Я написал следующие функции, чтобы попытаться выполнить это.

Я столкнулся с проблемой, при которой я пытался читать из стандартного вывода, и он был пустым, и это привело к блокировке моей программы. Чтобы попытаться обойти это, я написал 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
    }
}

Пожалуйста, дайте мне знать, если вам нужна какая-либо другая информация.

1 Ответ

0 голосов
/ 26 июня 2018

Запустите программу чтения одного сеанса. Эта программа читает из сеанса и отправляет данные в канал.

В основной процедуре выберите в цикле случаи с полученными данными и тайм-аут. Обработайте каждый случай соответствующим образом.

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
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...