B4X
B4X
Read an SSH Channel Until Output Goes Quiet
See more SSH Examples
Demonstrates the Chilkat Ssh.ChannelReadAndPoll method, which reads a channel in two phases: it waits for the first channel message, then keeps processing until no further data arrives for the given number of milliseconds. The first argument is the channel number and the second is the second-phase poll timeout.
The integer return value is -1 on error, -2 if nothing arrived before the timeout, 0 if EOF or channel close was processed, or — when greater than 0 — the total bytes currently buffered for the channel (not the bytes newly received by this call).
Background: This solves the practical problem of "read everything the command produced" when the channel is not going to close — an interactive shell, for example, stays open after each command. Waiting for a quiet period is a pragmatic stand-in for an end-of-output marker. The initial wait is governed by
ReadTimeoutMs (or IdleTimeoutMs when that is zero), while the argument controls only the quiet-period phase.Chilkat B4X Downloads
Dim success As Boolean = False
' Demonstrates the Ssh.ChannelReadAndPoll method, which reads a channel in two phases: it waits
' for the first channel message, then keeps processing until no more data arrives for the given
' number of milliseconds. The 1st argument is the channel number and the 2nd is the poll
' timeout for the second phase.
Dim ssh As ChilkatSsh
ssh.Initialize("ssh")
Dim sshPort As Int = 22
success = ssh.Connect("ssh.example.com", sshPort)
If success = False Then
Log(ssh.LastErrorText)
Return
End If
' Normally you would not hard-code the password in source. You should instead obtain it
' from an interactive prompt, environment variable, or a secrets vault.
Dim password As String = "mySshPassword"
success = ssh.AuthenticatePw("mySshLogin", password)
If success = False Then
Log(ssh.LastErrorText)
Return
End If
Dim channelNum As Int = ssh.OpenSessionChannel
If channelNum < 0 Then
Log(ssh.LastErrorText)
Return
End If
' Start a shell WITHOUT requesting a PTY. Without a PTY the shell sees it is connected to a
' raw data pipe and enters non-interactive mode: it suppresses the command prompt, does not
' echo typed commands back, and skips interactive login scripts. The output is therefore
' clean and easily parseable -- but because no prompt is ever sent, code must not wait for
' one. Instead, have each command print a predictable marker, or wait for EOF / channel close.
success = ssh.SendReqShell(channelNum)
If success = False Then
Log(ssh.LastErrorText)
Return
End If
success = ssh.ChannelSendString(channelNum, "ls -l /usr/bin" & Chr(10), "utf-8")
If success = False Then
Log(ssh.LastErrorText)
Return
End If
' Keep reading until the output goes quiet for 500 milliseconds.
Dim pollTimeoutMs As Int = 500
' The return value is: -1 on error, -2 if nothing arrived before the timeout, 0 if EOF or
' channel close was processed, or the total number of buffered bytes when greater than 0.
Dim result As Int = ssh.ChannelReadAndPoll(channelNum, pollTimeoutMs)
If result = -1 Then
Log(ssh.LastErrorText)
Return
End If
If result = -2 Then
Log("No channel data arrived before the timeout.")
End If
If result = 0 Then
Log("EOF or channel close was processed. Buffered data may still remain.")
End If
If result > 0 Then
Log("Total bytes buffered: " & result)
End If
Dim output As String = ssh.GetReceivedText(channelNum, "utf-8")
If ssh.LastMethodSuccess = False Then
Log(ssh.LastErrorText)
Return
End If
Log(output)
ssh.Disconnect