class io.SshChannel
Overview
This class provides high-level asynchronous interface for client-side SSH connections. More…
import "io_ssh.jncx" class SshChannel { // fields io.SshEvents readonly volatile m_activeEvents; std.Error const* readonly volatile m_ioError; bool readonly m_isOpen; // properties io.SocketAddress const property m_address; io.SocketAddress const property m_peerAddress; size_t autoget property m_readBlockSize; size_t autoget property m_readBufferSize; size_t autoget property m_writeBufferSize; io.SocketOptions autoget property m_options; // construction construct(); destruct(); // methods bool errorcode open(io.AddressFamily family); bool errorcode open(io.SocketAddress const* address); void close(); bool errorcode connect( io.SocketAddress const* address, string_t userName, string_t password, string_t channelType = "session", string_t processType = "shell", string_t ptyType = "xterm", uint_t ptyWidth = 80, uint_t ptyHeight = 24 ); bool errorcode connect(io.SshConnectParams const* params); bool errorcode authenticate( string_t userName, string_t password ); bool errorcode authenticate( string_t userName, string_t privateKeyFileName, string_t passphrase ); bool errorcode authenticate( string_t userName, void const* privateKey, size_t privateKeySize, string_t passphrase ); bool errorcode resizePty( uint_t width, uint_t height ); size_t errorcode read( void* p, size_t size ); size_t errorcode write( void const* p, size_t size ); long errorcode wait( io.SshEvents eventMask, void function* handler(io.SshEvents triggeredEvents) ); bool errorcode cancelWait(long handle); io.SshEvents blockingWait( io.SshEvents eventMask, uint_t timeout = -1 ); io.SshEvents async asyncWait(io.SshEvents eventMask); // aliases alias dispose = close; };
Detailed Documentation
This class provides high-level asynchronous interface for client-side SSH connections.
Under the hood io.SshChannel
uses libssh2 library.
A typical sequence of steps when establishing an SSH connection looks like this:
Call
open
method to open underlying socket;Call
connect
method to initate connection toSSH
server;Assign IO event handler with
wait
method. You would probably also want to schedule your event handler to be run in particular environment(e.g., in a specific thread) and partially apply some syncrhonization ID to discard late events;If
io.SshEvents.SshAuthenticateError
event is fired, you can re-authenticate usingauthenticate
method;Wait until
io.SshEvents.SshConnectCompleted
orio.SshEvents.IoError
event;When
io.SshEvents.IncomingData
event is fired, read from the file usingread
method;Write to the file stream using
write
method;Suspend writing if the return value of
write
is less than requested;Resume writing on
io.SshEvents.WriteBufferReady
event;Close the SSH channel when no longer needed with
close
method.
Sample code:
class MyDialog { // ... io.SshChannel m_ssh; uint_t m_syncId; construct(); void open( string_t portName, uint_t baudRate ); void close(); void waitSshEvents(); void onWriteButtonClicked(); void onSshEvent( uint_t syncId, io.SshEvents triggeredEvents ); } MyDialog.connect( string_t addrString, string_t userName, string_t password ) { io.SocketAddress sockAddr; sockAddr.parse(addrString); m_ssh.open(); m_ssh.connect(sockAddr, userName, password); waitSshEvents(); catch: // handle the error... } MyDialog.close() { m_serial.close(); m_syncId++; // events past this point will be discarded as 'late' } MyDialog.waitSshEvent() { io.SshEvents eventMask = io.SshEvents.IoError | io.SshEvents.SshAuthenticateError | io.SshEvents.IncomingData; if (!(m_ssh.m_activeEvents & io.SshEvents.SshConnectCompleted)) eventMask |= io.SshEvents.SshConnectCompleted; m_ssh.wait(eventMask, onPcapEvent ~(++m_syncId) @ g_mainThreadScheduler); } MyDialog.onWriteButtonClicked() { static char data[] = "a quick brown fox jumps over the lazy dog"; m_ssh.write(data, sizeof(data)); } MyDialog.onSshEvent( uint_t syncId, io.SshEvents triggeredEvents ) { if (syncId != m_syncId) // late event return; if (triggeredEvents & io.SshEvents.IoError) { string_t errorString = m_ssh.m_ioError.m_description; // ... } if (triggeredEvents & io.SshEvents.SshAuthenticateError) { // show some kind of login dialog ... // ... // ... then re-authenticate: m_ssh.authenticate(userName, password); } if (triggeredEvents & io.SshEvents.SshConnectCompleted) { // SSH channel established } if (triggeredEvents & io.SshEvents.IncomingData) { char buffer[256]; size_t size = m_ssh.read(buffer, sizeof(buffer)); // ... } waitSshEvents(); // restart wait }
See also:
io.SshEvents
, io.Socket
, io.SocketAddress
,
io.HostNameResolver
Fields
bool readonly m_isOpen
Holds the open status for the socket, i.e. true
if opened; false
otherwise.
Properties
io.SocketAddress const property m_address
This property is used for getting the local address assigned to this socket. If the address has not been assigned yet, returns empty address.
io.SocketAddress const property m_peerAddress
This property is used for getting the remote address of the peer this socket is connected to. If the connection has not been established yet, returns empty address.
Methods
bool errorcode open(io.AddressFamily family)
Opens a TCP
socket this connection will use for transport.
Returns true
on success. If a new socket could not be opened, IO
error supplied by operating system is set and then the function returns
false
[1].
bool errorcode open(io.SocketAddress const* address)
Opens a TCP
socket this connection will use for transport.
Returns true
on success. If a new socket could not be opened, IO
error supplied by operating system is set and then the function returns
false
[1].
void close()
Closes SSH
channel and underlying TCP
socket; does nothing if
connection is not and not being established.
Sometimes it may be convenient to use disposable pattern to ensure
timely invokation of close
[2].
bool errorcode connect( io.SocketAddress const* address, string_t userName, string_t password, string_t channelType = "session", string_t processType = "shell", string_t ptyType = "xterm", uint_t ptyWidth = 80, uint_t ptyHeight = 24 )
Initiates a connection request to address
.
The meanings of the arguments for this function are as follows:
address
specifes the remoteSSH
server to connect to;userName
andpassword
specify user credential used to login to this SSH server;channelType
specifies the type of the channel to establish (typically,session
; can also bedirect-tcpip
,tcpip-forward
, etc);processType
specifies what kind of process to run on the server side of thisSSH
channel(typically,shell
; can also beexec
,subsystem
etc);ptyType
specifies what type of pseudo terminal kind of process to run on the server side of thisSSH
channel(typically,xterm
; can also beansi
,vanilla
etc);ptyWidth
andptyHeight
specify the size of the pseudo-terminal;isSync
specifies whether this is a synchronous connect.
Returns true
on success. If a connection could not be initiated,
corresponding error is set and then the function returns false
[1].
bool errorcode authenticate( string_t userName, string_t password )
Sends a request to SSH server to re-authenticate on AuthError
event.
Returns true
on success. If re-authenticate request could not be
sent, returns false
[1].
bool errorcode resizePty( uint_t width, uint_t height )
Sends a request to SSH server to resize pseudo-terminal to width
x
height
. If isSync
is true
then this method does not return
until the remote server completes the request.
Returns true
on success. If pseudo-terminal could not be resized,
error returned by the remote server is set and then the function returns
false
[1].
size_t errorcode read( void* p, size_t size )
Attempts to receive up to size
bytes from the SSH socket into the
buffer pointed to by p
.
Returns the actual amount of bytes read on success. If read operation
is unsuccessful, IO error supplied by the operating system is set and
then the function returns -1
[1].
Normally you would call this function from within your event handler
for IncomingData
event. If this function is called when there is
no incoming data, it blocks until either the data arrives, or the socket
is closed.
size_t errorcode write( void const* p, size_t size )
Attempts to send size
bytes from the buffer pointed to by p
over
the established SSH channel.
Returns the actual amount of bytes written on success. If write
operation is unsuccessful, IO error supplied by the operating system is
set and then the function returns -1
[1].
If the return value shows less bytes than specified by size
argument, you should suspend further transmission until the file stream
is ready to accept more data. When this happens, WriteBufferReady
event is fired and transmission could be resumed.
Aliases
alias dispose = close
Effectively makes io.SshChannel
a disposable class [2].
Footnotes