# < Summary

Information

Class: | Renci.SshNet.Channels.Channel
Assembly: | Renci.SshNet
File(s): | \home\appveyor\projects\ssh-net\src\Renci.SshNet\Channels\Channel.cs

Line coverage
95%

Covered lines: | 360
Uncovered lines: | 16
Coverable lines: | 376
Total lines: | 875
Line coverage: | 95.7%

Branch coverage
88%

Covered branches: | 78
Total branches: | 88
Branch coverage: | 88.6%

Method coverage

Feature is only available for sponsors

Upgrade to PRO version

# Metrics

Method | Branch coverage | Cyclomatic complexity | Line coverage
--- | --- | --- | ---
.ctor(...) | 100% | 1 | 100%
get_Session() | 100% | 1 | 100%
get_LocalChannelNumber() | 100% | 1 | 100%
get_LocalPacketSize() | 100% | 1 | 100%
get_LocalWindowSize() | 100% | 1 | 100%
get_RemoteChannelNumber() | 50% | 2 | 66.66%
set_RemoteChannelNumber(...) | 100% | 1 | 100%
get_RemotePacketSize() | 50% | 2 | 66.66%
set_RemotePacketSize(...) | 100% | 1 | 100%
get_RemoteWindowSize() | 50% | 2 | 66.66%
set_RemoteWindowSize(...) | 100% | 1 | 100%
get_IsOpen() | 100% | 1 | 100%
get_IsConnected() | 100% | 1 | 100%
get_ConnectionInfo() | 100% | 1 | 100%
get_SessionSemaphore() | 100% | 1 | 100%
InitializeRemoteInfo(...) | 100% | 1 | 100%
SendData(...) | 100% | 1 | 100%
SendData(...) | 100% | 4 | 100%
OnWindowAdjust(...) | 100% | 1 | 100%
OnData(...) | 100% | 2 | 100%
OnExtendedData(...) | 50% | 2 | 100%
OnEof() | 100% | 2 | 100%
OnClose() | 100% | 2 | 100%
OnRequest(...) | 100% | 2 | 100%
OnSuccess() | 50% | 2 | 100%
OnFailure() | 50% | 2 | 100%
RaiseExceptionEvent(...) | 50% | 2 | 100%
TrySendMessage(...) | 100% | 1 | 100%
SendMessage(...) | 50% | 2 | 66.66%
SendEof() | 100% | 2 | 100%
WaitOnHandle(...) | 100% | 1 | 100%
Close() | 100% | 28 | 100%
OnDisconnected() | 100% | 1 | 100%
OnErrorOccured(...) | 100% | 1 | 100%
Session_Disconnected(...) | 100% | 1 | 100%
OnChannelException(...) | 100% | 1 | 100%
Session_ErrorOccured(...) | 100% | 1 | 100%
OnChannelWindowAdjust(...) | 100% | 2 | 91.66%
OnChannelData(...) | 100% | 2 | 91.66%
OnChannelExtendedData(...) | 100% | 2 | 91.66%
OnChannelEof(...) | 100% | 2 | 100%
OnChannelClose(...) | 100% | 2 | 100%
OnChannelRequest(...) | 75% | 4 | 77.77%
OnChannelSuccess(...) | 100% | 2 | 91.66%
OnChannelFailure(...) | 100% | 2 | 91.66%
AdjustDataWindow(...) | 50% | 2 | 50%
GetDataLengthThatCanBeSentInMessage(...) | 100% | 2 | 100%
CreateRemoteChannelInfoNotAvailableException() | 100% | 1 | 0%
CreateChannelClosedException() | 100% | 1 | 100%
Dispose() | 100% | 1 | 100%
Dispose(...) | 100% | 8 | 100%
Finalize() | 100% | 1 | 100%

# File(s)

## \home\appveyor\projects\ssh-net\src\Renci.SshNet\Channels\Channel.cs

| # | Line |  | Line coverage
--- | --- | --- | --- | ---
|  | `1` |  | `using System;`
|  | `2` |  | `using System.Globalization;`
|  | `3` |  | `using System.Net.Sockets;`
|  | `4` |  | `using System.Threading;`
|  | `5` |  | ``
|  | `6` |  | `using Renci.SshNet.Abstractions;`
|  | `7` |  | `using Renci.SshNet.Common;`
|  | `8` |  | `using Renci.SshNet.Messages;`
|  | `9` |  | `using Renci.SshNet.Messages.Connection;`
|  | `10` |  | ``
|  | `11` |  | `namespace Renci.SshNet.Channels`
|  | `12` |  | `{`
|  | `13` |  | `/// <summary>`
|  | `14` |  | `/// Represents base class for SSH channel implementations.`
|  | `15` |  | `/// </summary>`
|  | `16` |  | `internal abstract class Channel : IChannel`
|  | `17` |  | `{`
| 2288 | `18` |  | `private readonly object _serverWindowSizeLock = new object();`
| 2288 | `19` |  | `private readonly object _messagingLock = new object();`
|  | `20` |  | `private readonly uint _initialWindowSize;`
|  | `21` |  | `private readonly ISession _session;`
| 2288 | `22` |  | `private EventWaitHandle _channelClosedWaitHandle = new ManualResetEvent(initialState: false);`
| 2288 | `23` |  | `private EventWaitHandle _channelServerWindowAdjustWaitHandle = new ManualResetEvent(initialState: false);`
|  | `24` |  | `private uint? _remoteWindowSize;`
|  | `25` |  | `private uint? _remoteChannelNumber;`
|  | `26` |  | `private uint? _remotePacketSize;`
|  | `27` |  | `private bool _isDisposed;`
|  | `28` |  | ``
|  | `29` |  | `/// <summary>`
|  | `30` |  | `/// Holds a value indicating whether the SSH_MSG_CHANNEL_CLOSE has been sent to the remote party.`
|  | `31` |  | `/// </summary>`
|  | `32` |  | `/// <value>`
|  | `33` |  | `/// <see langword="true"/> when a SSH_MSG_CHANNEL_CLOSE message has been sent to the other party;`
|  | `34` |  | `/// otherwise, <see langword="false"/>.`
|  | `35` |  | `/// </value>`
|  | `36` |  | `private bool _closeMessageSent;`
|  | `37` |  | ``
|  | `38` |  | `/// <summary>`
|  | `39` |  | `/// Holds a value indicating whether a SSH_MSG_CHANNEL_CLOSE has been received from the other`
|  | `40` |  | `/// party.`
|  | `41` |  | `/// </summary>`
|  | `42` |  | `/// <value>`
|  | `43` |  | `/// <see langword="true"/> when a SSH_MSG_CHANNEL_CLOSE message has been received from the other party;`
|  | `44` |  | `/// otherwise, <see langword="false"/>.`
|  | `45` |  | `/// </value>`
|  | `46` |  | `private bool _closeMessageReceived;`
|  | `47` |  | ``
|  | `48` |  | `/// <summary>`
|  | `49` |  | `/// Holds a value indicating whether the SSH_MSG_CHANNEL_EOF has been received from the other party.`
|  | `50` |  | `/// </summary>`
|  | `51` |  | `/// <value>`
|  | `52` |  | `/// <see langword="true"/> when a SSH_MSG_CHANNEL_EOF message has been received from the other party;`
|  | `53` |  | `/// otherwise, <see langword="false"/>.`
|  | `54` |  | `/// </value>`
|  | `55` |  | `private bool _eofMessageReceived;`
|  | `56` |  | ``
|  | `57` |  | `/// <summary>`
|  | `58` |  | `/// Holds a value indicating whether the SSH_MSG_CHANNEL_EOF has been sent to the remote party.`
|  | `59` |  | `/// </summary>`
|  | `60` |  | `/// <value>`
|  | `61` |  | `/// <see langword="true"/> when a SSH_MSG_CHANNEL_EOF message has been sent to the remote party;`
|  | `62` |  | `/// otherwise, <see langword="false"/>.`
|  | `63` |  | `/// </value>`
|  | `64` |  | `private bool _eofMessageSent;`
|  | `65` |  | ``
|  | `66` |  | `/// <summary>`
|  | `67` |  | `/// Occurs when an exception is thrown when processing channel messages.`
|  | `68` |  | `/// </summary>`
|  | `69` |  | `public event EventHandler<ExceptionEventArgs> Exception;`
|  | `70` |  | ``
|  | `71` |  | `/// <summary>`
|  | `72` |  | `/// Initializes a new instance of the <see cref="Channel"/> class.`
|  | `73` |  | `/// </summary>`
|  | `74` |  | `/// <param name="session">The session.</param>`
|  | `75` |  | `/// <param name="localChannelNumber">The local channel number.</param>`
|  | `76` |  | `/// <param name="localWindowSize">Size of the window.</param>`
|  | `77` |  | `/// <param name="localPacketSize">Size of the packet.</param>`
| 2288 | `78` |  | `protected Channel(ISession session, uint localChannelNumber, uint localWindowSize, uint localPacketSize)`
| 2288 | `79` |  | `{`
| 2288 | `80` |  | `_session = session;`
| 2288 | `81` |  | `_initialWindowSize = localWindowSize;`
| 2288 | `82` |  | `LocalChannelNumber = localChannelNumber;`
| 2288 | `83` |  | `LocalPacketSize = localPacketSize;`
| 2288 | `84` |  | `LocalWindowSize = localWindowSize;`
|  | `85` |  | ``
| 2288 | `86` |  | `session.ChannelWindowAdjustReceived += OnChannelWindowAdjust;`
| 2288 | `87` |  | `session.ChannelDataReceived += OnChannelData;`
| 2288 | `88` |  | `session.ChannelExtendedDataReceived += OnChannelExtendedData;`
| 2288 | `89` |  | `session.ChannelEofReceived += OnChannelEof;`
| 2288 | `90` |  | `session.ChannelCloseReceived += OnChannelClose;`
| 2288 | `91` |  | `session.ChannelRequestReceived += OnChannelRequest;`
| 2288 | `92` |  | `session.ChannelSuccessReceived += OnChannelSuccess;`
| 2288 | `93` |  | `session.ChannelFailureReceived += OnChannelFailure;`
| 2288 | `94` |  | `session.ErrorOccured += Session_ErrorOccured;`
| 2288 | `95` |  | `session.Disconnected += Session_Disconnected;`
| 2288 | `96` |  | `}`
|  | `97` |  | ``
|  | `98` |  | `/// <summary>`
|  | `99` |  | `/// Gets the session.`
|  | `100` |  | `/// </summary>`
|  | `101` |  | `/// <value>`
|  | `102` |  | `/// Thhe session.`
|  | `103` |  | `/// </value>`
|  | `104` |  | `protected ISession Session`
|  | `105` |  | `{`
| 12186 | `106` |  | `get { return _session; }`
|  | `107` |  | `}`
|  | `108` |  | ``
|  | `109` |  | `/// <summary>`
|  | `110` |  | `/// Gets the type of the channel.`
|  | `111` |  | `/// </summary>`
|  | `112` |  | `/// <value>`
|  | `113` |  | `/// The type of the channel.`
|  | `114` |  | `/// </value>`
|  | `115` |  | `public abstract ChannelTypes ChannelType { get; }`
|  | `116` |  | ``
|  | `117` |  | `/// <summary>`
|  | `118` |  | `/// Gets the local channel number.`
|  | `119` |  | `/// </summary>`
|  | `120` |  | `/// <value>`
|  | `121` |  | `/// The local channel number.`
|  | `122` |  | `/// </value>`
| 97254 | `123` |  | `public uint LocalChannelNumber { get; private set; }`
|  | `124` |  | ``
|  | `125` |  | `/// <summary>`
|  | `126` |  | `/// Gets the maximum size of a data packet that we can receive using the channel.`
|  | `127` |  | `/// </summary>`
|  | `128` |  | `/// <value>`
|  | `129` |  | `/// The maximum size of a packet.`
|  | `130` |  | `/// </value>`
|  | `131` |  | `/// <remarks>`
|  | `132` |  | `/// <para>`
|  | `133` |  | `/// This is the maximum size (in bytes) we support for the data (payload) of a`
|  | `134` |  | `/// <c>SSH_MSG_CHANNEL_DATA</c> message we receive.`
|  | `135` |  | `/// </para>`
|  | `136` |  | `/// <para>`
|  | `137` |  | `/// We currently do not enforce this limit.`
|  | `138` |  | `/// </para>`
|  | `139` |  | `/// </remarks>`
| 39454 | `140` |  | `public uint LocalPacketSize { get; private set; }`
|  | `141` |  | ``
|  | `142` |  | `/// <summary>`
|  | `143` |  | `/// Gets the size of the local window.`
|  | `144` |  | `/// </summary>`
|  | `145` |  | `/// <value>`
|  | `146` |  | `/// The size of the local window.`
|  | `147` |  | `/// </value>`
| 108757 | `148` |  | `public uint LocalWindowSize { get; private set; }`
|  | `149` |  | ``
|  | `150` |  | `/// <summary>`
|  | `151` |  | `/// Gets the remote channel number.`
|  | `152` |  | `/// </summary>`
|  | `153` |  | `/// <value>`
|  | `154` |  | `/// The remote channel number.`
|  | `155` |  | `/// </value>`
|  | `156` |  | `public uint RemoteChannelNumber`
|  | `157` |  | `{`
|  | `158` |  | `get`
| 41801 | `159` |  | `{`
| 41801 | `160` |  | `if (!_remoteChannelNumber.HasValue)`
| 0 | `161` |  | `{`
| 0 | `162` |  | `throw CreateRemoteChannelInfoNotAvailableException();`
|  | `163` |  | `}`
|  | `164` |  | ``
| 41801 | `165` |  | `return _remoteChannelNumber.Value;`
| 41801 | `166` |  | `}`
|  | `167` |  | `private set`
| 2153 | `168` |  | `{`
| 2153 | `169` |  | `_remoteChannelNumber = value;`
| 2153 | `170` |  | `}`
|  | `171` |  | `}`
|  | `172` |  | ``
|  | `173` |  | `/// <summary>`
|  | `174` |  | `/// Gets the maximum size of a data packet that we can send using the channel.`
|  | `175` |  | `/// </summary>`
|  | `176` |  | `/// <value>`
|  | `177` |  | `/// The maximum size of data that can be sent using a <see cref="ChannelDataMessage"/>`
|  | `178` |  | `/// on the current channel.`
|  | `179` |  | `/// </value>`
|  | `180` |  | `/// <exception cref="InvalidOperationException">The channel has not been opened, or the open has not yet been co`
|  | `181` |  | `public uint RemotePacketSize`
|  | `182` |  | `{`
|  | `183` |  | `get`
| 37276 | `184` |  | `{`
| 37276 | `185` |  | `if (!_remotePacketSize.HasValue)`
| 0 | `186` |  | `{`
| 0 | `187` |  | `throw CreateRemoteChannelInfoNotAvailableException();`
|  | `188` |  | `}`
|  | `189` |  | ``
| 37276 | `190` |  | `return _remotePacketSize.Value;`
| 37276 | `191` |  | `}`
|  | `192` |  | `private set`
| 2153 | `193` |  | `{`
| 2153 | `194` |  | `_remotePacketSize = value;`
| 2153 | `195` |  | `}`
|  | `196` |  | `}`
|  | `197` |  | ``
|  | `198` |  | `/// <summary>`
|  | `199` |  | `/// Gets the window size of the remote server.`
|  | `200` |  | `/// </summary>`
|  | `201` |  | `/// <value>`
|  | `202` |  | `/// The size of the server window.`
|  | `203` |  | `/// </value>`
|  | `204` |  | `public uint RemoteWindowSize`
|  | `205` |  | `{`
|  | `206` |  | `get`
| 77214 | `207` |  | `{`
| 77214 | `208` |  | `if (!_remoteWindowSize.HasValue)`
| 0 | `209` |  | `{`
| 0 | `210` |  | `throw CreateRemoteChannelInfoNotAvailableException();`
|  | `211` |  | `}`
|  | `212` |  | ``
| 77214 | `213` |  | `return _remoteWindowSize.Value;`
| 77214 | `214` |  | `}`
|  | `215` |  | `private set`
| 42346 | `216` |  | `{`
| 42346 | `217` |  | `_remoteWindowSize = value;`
| 42346 | `218` |  | `}`
|  | `219` |  | `}`
|  | `220` |  | ``
|  | `221` |  | `/// <summary>`
|  | `222` |  | `/// Gets or sets a value indicating whether this channel is open.`
|  | `223` |  | `/// </summary>`
|  | `224` |  | `/// <value>`
|  | `225` |  | `/// <see langword="true"/> if this channel is open; otherwise, <see langword="false"/>.`
|  | `226` |  | `/// </value>`
| 103744 | `227` |  | `public bool IsOpen { get; protected set; }`
|  | `228` |  | ``
|  | `229` |  | `/// <summary>`
|  | `230` |  | `/// Occurs when <see cref="ChannelDataMessage"/> is received.`
|  | `231` |  | `/// </summary>`
|  | `232` |  | `public event EventHandler<ChannelDataEventArgs> DataReceived;`
|  | `233` |  | ``
|  | `234` |  | `/// <summary>`
|  | `235` |  | `/// Occurs when <see cref="ChannelExtendedDataMessage"/> is received.`
|  | `236` |  | `/// </summary>`
|  | `237` |  | `public event EventHandler<ChannelExtendedDataEventArgs> ExtendedDataReceived;`
|  | `238` |  | ``
|  | `239` |  | `/// <summary>`
|  | `240` |  | `/// Occurs when <see cref="ChannelEofMessage"/> is received.`
|  | `241` |  | `/// </summary>`
|  | `242` |  | `public event EventHandler<ChannelEventArgs> EndOfData;`
|  | `243` |  | ``
|  | `244` |  | `/// <summary>`
|  | `245` |  | `/// Occurs when <see cref="ChannelCloseMessage"/> is received.`
|  | `246` |  | `/// </summary>`
|  | `247` |  | `public event EventHandler<ChannelEventArgs> Closed;`
|  | `248` |  | ``
|  | `249` |  | `/// <summary>`
|  | `250` |  | `/// Occurs when <see cref="ChannelRequestMessage"/> is received.`
|  | `251` |  | `/// </summary>`
|  | `252` |  | `public event EventHandler<ChannelRequestEventArgs> RequestReceived;`
|  | `253` |  | ``
|  | `254` |  | `/// <summary>`
|  | `255` |  | `/// Occurs when <see cref="ChannelSuccessMessage"/> is received.`
|  | `256` |  | `/// </summary>`
|  | `257` |  | `public event EventHandler<ChannelEventArgs> RequestSucceeded;`
|  | `258` |  | ``
|  | `259` |  | `/// <summary>`
|  | `260` |  | `/// Occurs when <see cref="ChannelFailureMessage"/> is received.`
|  | `261` |  | `/// </summary>`
|  | `262` |  | `public event EventHandler<ChannelEventArgs> RequestFailed;`
|  | `263` |  | ``
|  | `264` |  | `/// <summary>`
|  | `265` |  | `/// Gets a value indicating whether the session is connected.`
|  | `266` |  | `/// </summary>`
|  | `267` |  | `/// <value>`
|  | `268` |  | `/// <see langword="true"/> if the session is connected; otherwise, <see langword="false"/>.`
|  | `269` |  | `/// </value>`
|  | `270` |  | `protected bool IsConnected`
|  | `271` |  | `{`
| 9852 | `272` |  | `get { return _session.IsConnected; }`
|  | `273` |  | `}`
|  | `274` |  | ``
|  | `275` |  | `/// <summary>`
|  | `276` |  | `/// Gets the connection info.`
|  | `277` |  | `/// </summary>`
|  | `278` |  | `/// <value>The connection info.</value>`
|  | `279` |  | `protected IConnectionInfo ConnectionInfo`
|  | `280` |  | `{`
| 15381 | `281` |  | `get { return _session.ConnectionInfo; }`
|  | `282` |  | `}`
|  | `283` |  | ``
|  | `284` |  | `/// <summary>`
|  | `285` |  | `/// Gets the session semaphore to control number of session channels.`
|  | `286` |  | `/// </summary>`
|  | `287` |  | `/// <value>The session semaphore.</value>`
|  | `288` |  | `protected SemaphoreLight SessionSemaphore`
|  | `289` |  | `{`
| 11979 | `290` |  | `get { return _session.SessionSemaphore; }`
|  | `291` |  | `}`
|  | `292` |  | ``
|  | `293` |  | `/// <summary>`
|  | `294` |  | `/// Initializes the information on the remote channel.`
|  | `295` |  | `/// </summary>`
|  | `296` |  | `/// <param name="remoteChannelNumber">The remote channel number.</param>`
|  | `297` |  | `/// <param name="remoteWindowSize">The remote window size.</param>`
|  | `298` |  | `/// <param name="remotePacketSize">The remote packet size.</param>`
|  | `299` |  | `protected void InitializeRemoteInfo(uint remoteChannelNumber, uint remoteWindowSize, uint remotePacketSize)`
| 2153 | `300` |  | `{`
| 2153 | `301` |  | `RemoteChannelNumber = remoteChannelNumber;`
| 2153 | `302` |  | `RemoteWindowSize = remoteWindowSize;`
| 2153 | `303` |  | `RemotePacketSize = remotePacketSize;`
| 2153 | `304` |  | `}`
|  | `305` |  | ``
|  | `306` |  | `/// <summary>`
|  | `307` |  | `/// Sends a SSH_MSG_CHANNEL_DATA message with the specified payload.`
|  | `308` |  | `/// </summary>`
|  | `309` |  | `/// <param name="data">The payload to send.</param>`
|  | `310` |  | `public void SendData(byte[] data)`
| 33076 | `311` |  | `{`
| 33076 | `312` |  | `SendData(data, 0, data.Length);`
| 33074 | `313` |  | `}`
|  | `314` |  | ``
|  | `315` |  | `/// <summary>`
|  | `316` |  | `/// Sends a SSH_MSG_CHANNEL_DATA message with the specified payload.`
|  | `317` |  | `/// </summary>`
|  | `318` |  | `/// <param name="data">An array of <see cref="byte"/> containing the payload to send.</param>`
|  | `319` |  | `/// <param name="offset">The zero-based offset in <paramref name="data"/> at which to begin taking data from.</p`
|  | `320` |  | `/// <param name="size">The number of bytes of <paramref name="data"/> to send.</param>`
|  | `321` |  | `/// <remarks>`
|  | `322` |  | `/// <para>`
|  | `323` |  | `/// When the size of the data to send exceeds the maximum packet size or the remote window`
|  | `324` |  | `/// size does not allow the full data to be sent, then this method will send the data in`
|  | `325` |  | `/// multiple chunks and will wait for the remote window size to be adjusted when it's zero.`
|  | `326` |  | `/// </para>`
|  | `327` |  | `/// <para>`
|  | `328` |  | `/// This is done to support SSH servers will a small window size that do not agressively`
|  | `329` |  | `/// increase their window size. We need to take into account that there may be SSH servers`
|  | `330` |  | `/// that only increase their window size when it has reached zero.`
|  | `331` |  | `/// </para>`
|  | `332` |  | `/// </remarks>`
|  | `333` |  | `public void SendData(byte[] data, int offset, int size)`
| 44058 | `334` |  | `{`
|  | `335` |  | `// send channel messages only while channel is open`
| 44058 | `336` |  | `if (!IsOpen)`
| 1 | `337` |  | `{`
| 1 | `338` |  | `return;`
|  | `339` |  | `}`
|  | `340` |  | ``
| 44057 | `341` |  | `var totalBytesToSend = size;`
| 80968 | `342` |  | `while (totalBytesToSend > 0)`
| 36913 | `343` |  | `{`
| 36913 | `344` |  | `var sizeOfCurrentMessage = GetDataLengthThatCanBeSentInMessage(totalBytesToSend);`
|  | `345` |  | ``
| 36913 | `346` |  | `var channelDataMessage = new ChannelDataMessage(RemoteChannelNumber,`
| 36913 | `347` |  | `data,`
| 36913 | `348` |  | `offset,`
| 36913 | `349` |  | `sizeOfCurrentMessage);`
| 36913 | `350` |  | `_session.SendMessage(channelDataMessage);`
|  | `351` |  | ``
| 36911 | `352` |  | `totalBytesToSend -= sizeOfCurrentMessage;`
| 36911 | `353` |  | `offset += sizeOfCurrentMessage;`
| 36911 | `354` |  | `}`
| 44056 | `355` |  | `}`
|  | `356` |  | ``
|  | `357` |  | `/// <summary>`
|  | `358` |  | `/// Called when channel window need to be adjust.`
|  | `359` |  | `/// </summary>`
|  | `360` |  | `/// <param name="bytesToAdd">The bytes to add.</param>`
|  | `361` |  | `protected virtual void OnWindowAdjust(uint bytesToAdd)`
| 3280 | `362` |  | `{`
| 3280 | `363` |  | `lock (_serverWindowSizeLock)`
| 3280 | `364` |  | `{`
| 3280 | `365` |  | `RemoteWindowSize += bytesToAdd;`
| 3280 | `366` |  | `}`
|  | `367` |  | ``
| 3280 | `368` |  | `_ = _channelServerWindowAdjustWaitHandle.Set();`
| 3280 | `369` |  | `}`
|  | `370` |  | ``
|  | `371` |  | `/// <summary>`
|  | `372` |  | `/// Called when channel data is received.`
|  | `373` |  | `/// </summary>`
|  | `374` |  | `/// <param name="data">The data.</param>`
|  | `375` |  | `protected virtual void OnData(byte[] data)`
| 34760 | `376` |  | `{`
| 34760 | `377` |  | `AdjustDataWindow(data);`
|  | `378` |  | ``
| 34760 | `379` |  | `DataReceived?.Invoke(this, new ChannelDataEventArgs(LocalChannelNumber, data));`
| 34760 | `380` |  | `}`
|  | `381` |  | ``
|  | `382` |  | `/// <summary>`
|  | `383` |  | `/// Called when channel extended data is received.`
|  | `384` |  | `/// </summary>`
|  | `385` |  | `/// <param name="data">The data.</param>`
|  | `386` |  | `/// <param name="dataTypeCode">The data type code.</param>`
|  | `387` |  | `protected virtual void OnExtendedData(byte[] data, uint dataTypeCode)`
| 46 | `388` |  | `{`
| 46 | `389` |  | `AdjustDataWindow(data);`
|  | `390` |  | ``
| 46 | `391` |  | `ExtendedDataReceived?.Invoke(this, new ChannelExtendedDataEventArgs(LocalChannelNumber, data, dataTypeCode))`
| 46 | `392` |  | `}`
|  | `393` |  | ``
|  | `394` |  | `/// <summary>`
|  | `395` |  | `/// Called when channel has no more data to receive.`
|  | `396` |  | `/// </summary>`
|  | `397` |  | `protected virtual void OnEof()`
| 1115 | `398` |  | `{`
| 1115 | `399` |  | `_eofMessageReceived = true;`
|  | `400` |  | ``
| 1115 | `401` |  | `EndOfData?.Invoke(this, new ChannelEventArgs(LocalChannelNumber));`
| 1115 | `402` |  | `}`
|  | `403` |  | ``
|  | `404` |  | `/// <summary>`
|  | `405` |  | `/// Called when channel is closed by the server.`
|  | `406` |  | `/// </summary>`
|  | `407` |  | `protected virtual void OnClose()`
| 2029 | `408` |  | `{`
| 2029 | `409` |  | `_closeMessageReceived = true;`
|  | `410` |  | ``
|  | `411` |  | `// Signal that SSH_MSG_CHANNEL_CLOSE message was received from server.`
|  | `412` |  | `// We need to signal this before invoking Close() as it may very well`
|  | `413` |  | `// be blocked waiting for this signal.`
| 2029 | `414` |  | `var channelClosedWaitHandle = _channelClosedWaitHandle;`
| 2029 | `415` |  | `if (channelClosedWaitHandle != null)`
| 2029 | `416` |  | `{`
| 2029 | `417` |  | `_ = channelClosedWaitHandle.Set();`
| 2029 | `418` |  | `}`
|  | `419` |  | ``
|  | `420` |  | `// close the channel`
| 2029 | `421` |  | `Close();`
| 2029 | `422` |  | `}`
|  | `423` |  | ``
|  | `424` |  | `/// <summary>`
|  | `425` |  | `/// Called when channel request received.`
|  | `426` |  | `/// </summary>`
|  | `427` |  | `/// <param name="info">Channel request information.</param>`
|  | `428` |  | `protected virtual void OnRequest(RequestInfo info)`
| 1698 | `429` |  | `{`
| 1698 | `430` |  | `RequestReceived?.Invoke(this, new ChannelRequestEventArgs(info));`
| 1698 | `431` |  | `}`
|  | `432` |  | ``
|  | `433` |  | `/// <summary>`
|  | `434` |  | `/// Called when channel request was successful.`
|  | `435` |  | `/// </summary>`
|  | `436` |  | `protected virtual void OnSuccess()`
| 1712 | `437` |  | `{`
| 1712 | `438` |  | `RequestSucceeded?.Invoke(this, new ChannelEventArgs(LocalChannelNumber));`
| 1712 | `439` |  | `}`
|  | `440` |  | ``
|  | `441` |  | `/// <summary>`
|  | `442` |  | `/// Called when channel request failed.`
|  | `443` |  | `/// </summary>`
|  | `444` |  | `protected virtual void OnFailure()`
| 7 | `445` |  | `{`
| 7 | `446` |  | `RequestFailed?.Invoke(this, new ChannelEventArgs(LocalChannelNumber));`
| 7 | `447` |  | `}`
|  | `448` |  | ``
|  | `449` |  | `/// <summary>`
|  | `450` |  | `/// Raises <see cref="Exception"/> event.`
|  | `451` |  | `/// </summary>`
|  | `452` |  | `/// <param name="exception">The exception.</param>`
|  | `453` |  | `private void RaiseExceptionEvent(Exception exception)`
| 72 | `454` |  | `{`
| 72 | `455` |  | `Exception?.Invoke(this, new ExceptionEventArgs(exception));`
| 72 | `456` |  | `}`
|  | `457` |  | ``
|  | `458` |  | `/// <summary>`
|  | `459` |  | `/// Sends a message to the server.`
|  | `460` |  | `/// </summary>`
|  | `461` |  | `/// <param name="message">The message to send.</param>`
|  | `462` |  | `/// <returns>`
|  | `463` |  | `/// <see langword="true"/> if the message was sent to the server; otherwise, <see langword="false"/>.`
|  | `464` |  | `/// </returns>`
|  | `465` |  | `/// <exception cref="InvalidOperationException">The size of the packet exceeds the maximum size defined by the p`
|  | `466` |  | `/// <remarks>`
|  | `467` |  | `/// This methods returns <see langword="false"/> when the attempt to send the message results in a`
|  | `468` |  | `/// <see cref="SocketException"/> or a <see cref="SshException"/>.`
|  | `469` |  | `/// </remarks>`
|  | `470` |  | `private bool TrySendMessage(Message message)`
| 3152 | `471` |  | `{`
| 3152 | `472` |  | `return _session.TrySendMessage(message);`
| 3152 | `473` |  | `}`
|  | `474` |  | ``
|  | `475` |  | `/// <summary>`
|  | `476` |  | `/// Sends SSH message to the server.`
|  | `477` |  | `/// </summary>`
|  | `478` |  | `/// <param name="message">The message.</param>`
|  | `479` |  | `protected void SendMessage(Message message)`
| 1707 | `480` |  | `{`
|  | `481` |  | `// Send channel messages only while channel is open`
| 1707 | `482` |  | `if (!IsOpen)`
| 0 | `483` |  | `{`
| 0 | `484` |  | `return;`
|  | `485` |  | `}`
|  | `486` |  | ``
| 1707 | `487` |  | `_session.SendMessage(message);`
| 1707 | `488` |  | `}`
|  | `489` |  | ``
|  | `490` |  | `/// <summary>`
|  | `491` |  | `/// Sends a SSH_MSG_CHANNEL_EOF message to the remote server.`
|  | `492` |  | `/// </summary>`
|  | `493` |  | `/// <exception cref="InvalidOperationException">The channel is closed.</exception>`
|  | `494` |  | `public void SendEof()`
| 27 | `495` |  | `{`
| 27 | `496` |  | `if (!IsOpen)`
| 15 | `497` |  | `{`
| 15 | `498` |  | `throw CreateChannelClosedException();`
|  | `499` |  | `}`
|  | `500` |  | ``
| 12 | `501` |  | `lock (_messagingLock)`
| 12 | `502` |  | `{`
| 12 | `503` |  | `_session.SendMessage(new ChannelEofMessage(RemoteChannelNumber));`
| 12 | `504` |  | `_eofMessageSent = true;`
| 12 | `505` |  | `}`
| 12 | `506` |  | `}`
|  | `507` |  | ``
|  | `508` |  | `/// <summary>`
|  | `509` |  | `/// Waits for the handle to be signaled or for an error to occurs.`
|  | `510` |  | `/// </summary>`
|  | `511` |  | `/// <param name="waitHandle">The wait handle.</param>`
|  | `512` |  | `protected void WaitOnHandle(WaitHandle waitHandle)`
| 3849 | `513` |  | `{`
| 3849 | `514` |  | `_session.WaitOnHandle(waitHandle);`
| 3834 | `515` |  | `}`
|  | `516` |  | ``
|  | `517` |  | `/// <summary>`
|  | `518` |  | `/// Closes the channel, waiting for the SSH_MSG_CHANNEL_CLOSE message to be received from the server.`
|  | `519` |  | `/// </summary>`
|  | `520` |  | `protected virtual void Close()`
| 4107 | `521` |  | `{`
|  | `522` |  | `/*`
|  | `523` |  | `* Synchronize sending SSH_MSG_CHANNEL_EOF and SSH_MSG_CHANNEL_CLOSE to ensure that these messages`
|  | `524` |  | `* are sent in that other; when both the client and the server attempt to close the channel at the`
|  | `525` |  | `* same time we would otherwise risk sending the SSH_MSG_CHANNEL_EOF after the SSH_MSG_CHANNEL_CLOSE`
|  | `526` |  | `* message causing the server to disconnect the session.`
|  | `527` |  | `*/`
|  | `528` |  | ``
| 4107 | `529` |  | `lock (_messagingLock)`
| 4107 | `530` |  | `{`
|  | `531` |  | `// Send EOF message first the following conditions are met:`
|  | `532` |  | `// * we have not sent a SSH_MSG_CHANNEL_EOF message`
|  | `533` |  | `// * remote party has not already sent a SSH_MSG_CHANNEL_EOF message`
|  | `534` |  | `// * remote party has not already sent a SSH_MSG_CHANNEL_CLOSE message`
|  | `535` |  | `// * the channel is open`
|  | `536` |  | `// * the session is connected`
| 4107 | `537` |  | `if (!_eofMessageSent && !_closeMessageReceived && !_eofMessageReceived && IsOpen && IsConnected)`
| 1099 | `538` |  | `{`
| 1099 | `539` |  | `if (TrySendMessage(new ChannelEofMessage(RemoteChannelNumber)))`
| 1084 | `540` |  | `{`
| 1084 | `541` |  | `_eofMessageSent = true;`
| 1084 | `542` |  | `}`
| 1099 | `543` |  | `}`
|  | `544` |  | ``
|  | `545` |  | `// send message to close the channel on the server when it has not already been sent`
|  | `546` |  | `// and the channel is open and the session is connected`
| 4107 | `547` |  | `if (!_closeMessageSent && IsOpen && IsConnected)`
| 2053 | `548` |  | `{`
| 2053 | `549` |  | `if (TrySendMessage(new ChannelCloseMessage(RemoteChannelNumber)))`
| 2017 | `550` |  | `{`
| 2017 | `551` |  | `_closeMessageSent = true;`
|  | `552` |  | ``
|  | `553` |  | `// only wait for the channel to be closed by the server if we didn't send a`
|  | `554` |  | `// SSH_MSG_CHANNEL_CLOSE as response to a SSH_MSG_CHANNEL_CLOSE sent by the`
|  | `555` |  | `// server`
| 2017 | `556` |  | `var closeWaitResult = _session.TryWait(_channelClosedWaitHandle, ConnectionInfo.ChannelCloseTime`
| 2017 | `557` |  | `if (closeWaitResult != WaitResult.Success)`
| 42 | `558` |  | `{`
| 42 | `559` |  | `DiagnosticAbstraction.Log(string.Format("Wait for channel close not successful: {0:G}.", clo`
| 42 | `560` |  | `}`
| 2017 | `561` |  | `}`
| 2053 | `562` |  | `}`
|  | `563` |  | ``
| 4107 | `564` |  | `if (IsOpen)`
| 2107 | `565` |  | `{`
|  | `566` |  | `// mark sure the channel is marked closed before we raise the Closed event`
|  | `567` |  | `// this also ensures don't raise the Closed event more than once`
| 2107 | `568` |  | `IsOpen = false;`
|  | `569` |  | ``
| 2107 | `570` |  | `if (_closeMessageReceived)`
| 2023 | `571` |  | `{`
|  | `572` |  | `// raise event signaling that both ends of the channel have been closed`
| 2023 | `573` |  | `Closed?.Invoke(this, new ChannelEventArgs(LocalChannelNumber));`
| 2023 | `574` |  | `}`
| 2107 | `575` |  | `}`
| 4107 | `576` |  | `}`
| 4107 | `577` |  | `}`
|  | `578` |  | ``
|  | `579` |  | `protected virtual void OnDisconnected()`
| 15 | `580` |  | `{`
| 15 | `581` |  | `}`
|  | `582` |  | ``
|  | `583` |  | `protected virtual void OnErrorOccured(Exception exp)`
| 9 | `584` |  | `{`
| 9 | `585` |  | `}`
|  | `586` |  | ``
|  | `587` |  | `private void Session_Disconnected(object sender, EventArgs e)`
| 15 | `588` |  | `{`
| 15 | `589` |  | `IsOpen = false;`
|  | `590` |  | ``
|  | `591` |  | `try`
| 15 | `592` |  | `{`
| 15 | `593` |  | `OnDisconnected();`
| 9 | `594` |  | `}`
| 6 | `595` |  | `catch (Exception ex)`
| 6 | `596` |  | `{`
| 6 | `597` |  | `OnChannelException(ex);`
| 6 | `598` |  | `}`
| 15 | `599` |  | `}`
|  | `600` |  | ``
|  | `601` |  | `/// <summary>`
|  | `602` |  | `/// Called when an <see cref="Exception"/> occurs while processing a channel message.`
|  | `603` |  | `/// </summary>`
|  | `604` |  | `/// <param name="ex">The <see cref="Exception"/>.</param>`
|  | `605` |  | `/// <remarks>`
|  | `606` |  | `/// This method will in turn invoke <see cref="OnErrorOccured(System.Exception)"/>, and`
|  | `607` |  | `/// raise the <see cref="Exception"/> event.`
|  | `608` |  | `/// </remarks>`
|  | `609` |  | `protected void OnChannelException(Exception ex)`
| 66 | `610` |  | `{`
| 66 | `611` |  | `OnErrorOccured(ex);`
| 66 | `612` |  | `RaiseExceptionEvent(ex);`
| 66 | `613` |  | `}`
|  | `614` |  | ``
|  | `615` |  | `private void Session_ErrorOccured(object sender, ExceptionEventArgs e)`
| 15 | `616` |  | `{`
|  | `617` |  | `try`
| 15 | `618` |  | `{`
| 15 | `619` |  | `OnErrorOccured(e.Exception);`
| 9 | `620` |  | `}`
| 6 | `621` |  | `catch (Exception ex)`
| 6 | `622` |  | `{`
| 6 | `623` |  | `RaiseExceptionEvent(ex);`
| 6 | `624` |  | `}`
| 15 | `625` |  | `}`
|  | `626` |  | ``
|  | `627` |  | `private void OnChannelWindowAdjust(object sender, MessageEventArgs<ChannelWindowAdjustMessage> e)`
| 4826 | `628` |  | `{`
| 4826 | `629` |  | `if (e.Message.LocalChannelNumber == LocalChannelNumber)`
| 3280 | `630` |  | `{`
|  | `631` |  | `try`
| 3280 | `632` |  | `{`
| 3280 | `633` |  | `OnWindowAdjust(e.Message.BytesToAdd);`
| 3274 | `634` |  | `}`
| 6 | `635` |  | `catch (Exception ex)`
| 6 | `636` |  | `{`
| 6 | `637` |  | `OnChannelException(ex);`
| 6 | `638` |  | `}`
| 3280 | `639` |  | `}`
| 4826 | `640` |  | `}`
|  | `641` |  | ``
|  | `642` |  | `private void OnChannelData(object sender, MessageEventArgs<ChannelDataMessage> e)`
| 38864 | `643` |  | `{`
| 38864 | `644` |  | `if (e.Message.LocalChannelNumber == LocalChannelNumber)`
| 34760 | `645` |  | `{`
|  | `646` |  | `try`
| 34760 | `647` |  | `{`
| 34760 | `648` |  | `OnData(e.Message.Data);`
| 34754 | `649` |  | `}`
| 6 | `650` |  | `catch (Exception ex)`
| 6 | `651` |  | `{`
| 6 | `652` |  | `OnChannelException(ex);`
| 6 | `653` |  | `}`
| 34760 | `654` |  | `}`
| 38864 | `655` |  | `}`
|  | `656` |  | ``
|  | `657` |  | `private void OnChannelExtendedData(object sender, MessageEventArgs<ChannelExtendedDataMessage> e)`
| 46 | `658` |  | `{`
| 46 | `659` |  | `if (e.Message.LocalChannelNumber == LocalChannelNumber)`
| 46 | `660` |  | `{`
|  | `661` |  | `try`
| 46 | `662` |  | `{`
| 46 | `663` |  | `OnExtendedData(e.Message.Data, e.Message.DataTypeCode);`
| 40 | `664` |  | `}`
| 6 | `665` |  | `catch (Exception ex)`
| 6 | `666` |  | `{`
| 6 | `667` |  | `OnChannelException(ex);`
| 6 | `668` |  | `}`
| 46 | `669` |  | `}`
| 46 | `670` |  | `}`
|  | `671` |  | ``
|  | `672` |  | `private void OnChannelEof(object sender, MessageEventArgs<ChannelEofMessage> e)`
| 1907 | `673` |  | `{`
| 1907 | `674` |  | `if (e.Message.LocalChannelNumber == LocalChannelNumber)`
| 1115 | `675` |  | `{`
|  | `676` |  | `try`
| 1115 | `677` |  | `{`
| 1115 | `678` |  | `OnEof();`
| 1109 | `679` |  | `}`
| 6 | `680` |  | `catch (Exception ex)`
| 6 | `681` |  | `{`
| 6 | `682` |  | `OnChannelException(ex);`
| 6 | `683` |  | `}`
| 1115 | `684` |  | `}`
| 1907 | `685` |  | `}`
|  | `686` |  | ``
|  | `687` |  | `private void OnChannelClose(object sender, MessageEventArgs<ChannelCloseMessage> e)`
| 2848 | `688` |  | `{`
| 2848 | `689` |  | `if (e.Message.LocalChannelNumber == LocalChannelNumber)`
| 2029 | `690` |  | `{`
|  | `691` |  | `try`
| 2029 | `692` |  | `{`
| 2029 | `693` |  | `OnClose();`
| 2023 | `694` |  | `}`
| 6 | `695` |  | `catch (Exception ex)`
| 6 | `696` |  | `{`
| 6 | `697` |  | `OnChannelException(ex);`
| 6 | `698` |  | `}`
| 2029 | `699` |  | `}`
| 2848 | `700` |  | `}`
|  | `701` |  | ``
|  | `702` |  | `private void OnChannelRequest(object sender, MessageEventArgs<ChannelRequestMessage> e)`
| 2554 | `703` |  | `{`
| 2554 | `704` |  | `if (e.Message.LocalChannelNumber == LocalChannelNumber)`
| 1698 | `705` |  | `{`
|  | `706` |  | `try`
| 1698 | `707` |  | `{`
| 1698 | `708` |  | `if (_session.ConnectionInfo.ChannelRequests.TryGetValue(e.Message.RequestName, out var requestInfo))`
| 1698 | `709` |  | `{`
|  | `710` |  | `// Load request specific data`
| 1698 | `711` |  | `requestInfo.Load(e.Message.RequestData);`
|  | `712` |  | ``
|  | `713` |  | `// Raise request specific event`
| 1698 | `714` |  | `OnRequest(requestInfo);`
| 1692 | `715` |  | `}`
|  | `716` |  | `else`
| 0 | `717` |  | `{`
|  | `718` |  | `// TODO: we should also send a SSH_MSG_CHANNEL_FAILURE message`
| 0 | `719` |  | `throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Request '{0}' is not`
|  | `720` |  | `}`
| 1692 | `721` |  | `}`
| 6 | `722` |  | `catch (Exception ex)`
| 6 | `723` |  | `{`
| 6 | `724` |  | `OnChannelException(ex);`
| 6 | `725` |  | `}`
| 1698 | `726` |  | `}`
| 2554 | `727` |  | `}`
|  | `728` |  | ``
|  | `729` |  | `private void OnChannelSuccess(object sender, MessageEventArgs<ChannelSuccessMessage> e)`
| 2589 | `730` |  | `{`
| 2589 | `731` |  | `if (e.Message.LocalChannelNumber == LocalChannelNumber)`
| 1712 | `732` |  | `{`
|  | `733` |  | `try`
| 1712 | `734` |  | `{`
| 1712 | `735` |  | `OnSuccess();`
| 1706 | `736` |  | `}`
| 6 | `737` |  | `catch (Exception ex)`
| 6 | `738` |  | `{`
| 6 | `739` |  | `OnChannelException(ex);`
| 6 | `740` |  | `}`
| 1712 | `741` |  | `}`
| 2589 | `742` |  | `}`
|  | `743` |  | ``
|  | `744` |  | `private void OnChannelFailure(object sender, MessageEventArgs<ChannelFailureMessage> e)`
| 7 | `745` |  | `{`
| 7 | `746` |  | `if (e.Message.LocalChannelNumber == LocalChannelNumber)`
| 7 | `747` |  | `{`
|  | `748` |  | `try`
| 7 | `749` |  | `{`
| 7 | `750` |  | `OnFailure();`
| 1 | `751` |  | `}`
| 6 | `752` |  | `catch (Exception ex)`
| 6 | `753` |  | `{`
| 6 | `754` |  | `OnChannelException(ex);`
| 6 | `755` |  | `}`
| 7 | `756` |  | `}`
| 7 | `757` |  | `}`
|  | `758` |  | ``
|  | `759` |  | `private void AdjustDataWindow(byte[] messageData)`
| 34806 | `760` |  | `{`
| 34806 | `761` |  | `LocalWindowSize -= (uint) messageData.Length;`
|  | `762` |  | ``
|  | `763` |  | `// Adjust window if window size is too low`
| 34806 | `764` |  | `if (LocalWindowSize < LocalPacketSize)`
| 0 | `765` |  | `{`
| 0 | `766` |  | `SendMessage(new ChannelWindowAdjustMessage(RemoteChannelNumber, _initialWindowSize - LocalWindowSize));`
| 0 | `767` |  | `LocalWindowSize = _initialWindowSize;`
| 0 | `768` |  | `}`
| 34806 | `769` |  | `}`
|  | `770` |  | ``
|  | `771` |  | `/// <summary>`
|  | `772` |  | `/// Determines the length of data that currently can be sent in a single message.`
|  | `773` |  | `/// </summary>`
|  | `774` |  | `/// <param name="messageLength">The length of the message that must be sent.</param>`
|  | `775` |  | `/// <returns>`
|  | `776` |  | `/// The actual data length that currently can be sent.`
|  | `777` |  | `/// </returns>`
|  | `778` |  | `private int GetDataLengthThatCanBeSentInMessage(int messageLength)`
| 36913 | `779` |  | `{`
|  | `780` |  | `do`
| 37021 | `781` |  | `{`
| 37021 | `782` |  | `lock (_serverWindowSizeLock)`
| 37021 | `783` |  | `{`
| 37021 | `784` |  | `var serverWindowSize = RemoteWindowSize;`
| 37021 | `785` |  | `if (serverWindowSize == 0U)`
| 108 | `786` |  | `{`
|  | `787` |  | `// Allow us to be signal when remote window size is adjusted`
| 108 | `788` |  | `_ = _channelServerWindowAdjustWaitHandle.Reset();`
| 108 | `789` |  | `}`
|  | `790` |  | `else`
| 36913 | `791` |  | `{`
| 36913 | `792` |  | `var bytesThatCanBeSent = Math.Min(Math.Min(RemotePacketSize, (uint) messageLength),`
| 36913 | `793` |  | `serverWindowSize);`
| 36913 | `794` |  | `RemoteWindowSize -= bytesThatCanBeSent;`
| 36913 | `795` |  | `return (int) bytesThatCanBeSent;`
|  | `796` |  | `}`
| 108 | `797` |  | `}`
|  | `798` |  | ``
|  | `799` |  | `// Wait for remote window size to change`
| 108 | `800` |  | `WaitOnHandle(_channelServerWindowAdjustWaitHandle);`
| 108 | `801` |  | `}`
| 108 | `802` |  | `while (true);`
| 36913 | `803` |  | `}`
|  | `804` |  | ``
|  | `805` |  | `private static InvalidOperationException CreateRemoteChannelInfoNotAvailableException()`
| 0 | `806` |  | `{`
| 0 | `807` |  | `throw new InvalidOperationException("The channel has not been opened, or the open has not yet been confirmed`
|  | `808` |  | `}`
|  | `809` |  | ``
|  | `810` |  | `private static InvalidOperationException CreateChannelClosedException()`
| 15 | `811` |  | `{`
| 15 | `812` |  | `throw new InvalidOperationException("The channel is closed.");`
|  | `813` |  | `}`
|  | `814` |  | ``
|  | `815` |  | `/// <summary>`
|  | `816` |  | `/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.`
|  | `817` |  | `/// </summary>`
|  | `818` |  | `public void Dispose()`
| 2138 | `819` |  | `{`
| 2138 | `820` |  | `Dispose(disposing: true);`
| 2138 | `821` |  | `GC.SuppressFinalize(this);`
| 2138 | `822` |  | `}`
|  | `823` |  | ``
|  | `824` |  | `/// <summary>`
|  | `825` |  | `/// Releases unmanaged and - optionally - managed resources.`
|  | `826` |  | `/// </summary>`
|  | `827` |  | `/// <param name="disposing"><see langword="true"/> to release both managed and unmanaged resources; <see langwor`
|  | `828` |  | `protected virtual void Dispose(bool disposing)`
| 2239 | `829` |  | `{`
| 2239 | `830` |  | `if (!_isDisposed && disposing)`
| 2078 | `831` |  | `{`
| 2078 | `832` |  | `Close();`
|  | `833` |  | ``
| 2078 | `834` |  | `var session = _session;`
| 2078 | `835` |  | `if (session is not null)`
| 2078 | `836` |  | `{`
| 2078 | `837` |  | `session.ChannelWindowAdjustReceived -= OnChannelWindowAdjust;`
| 2078 | `838` |  | `session.ChannelDataReceived -= OnChannelData;`
| 2078 | `839` |  | `session.ChannelExtendedDataReceived -= OnChannelExtendedData;`
| 2078 | `840` |  | `session.ChannelEofReceived -= OnChannelEof;`
| 2078 | `841` |  | `session.ChannelCloseReceived -= OnChannelClose;`
| 2078 | `842` |  | `session.ChannelRequestReceived -= OnChannelRequest;`
| 2078 | `843` |  | `session.ChannelSuccessReceived -= OnChannelSuccess;`
| 2078 | `844` |  | `session.ChannelFailureReceived -= OnChannelFailure;`
| 2078 | `845` |  | `session.ErrorOccured -= Session_ErrorOccured;`
| 2078 | `846` |  | `session.Disconnected -= Session_Disconnected;`
| 2078 | `847` |  | `}`
|  | `848` |  | ``
| 2078 | `849` |  | `var channelClosedWaitHandle = _channelClosedWaitHandle;`
| 2078 | `850` |  | `if (channelClosedWaitHandle is not null)`
| 2077 | `851` |  | `{`
| 2077 | `852` |  | `_channelClosedWaitHandle = null;`
| 2077 | `853` |  | `channelClosedWaitHandle.Dispose();`
| 2077 | `854` |  | `}`
|  | `855` |  | ``
| 2078 | `856` |  | `var channelServerWindowAdjustWaitHandle = _channelServerWindowAdjustWaitHandle;`
| 2078 | `857` |  | `if (channelServerWindowAdjustWaitHandle is not null)`
| 2077 | `858` |  | `{`
| 2077 | `859` |  | `_channelServerWindowAdjustWaitHandle = null;`
| 2077 | `860` |  | `channelServerWindowAdjustWaitHandle.Dispose();`
| 2077 | `861` |  | `}`
|  | `862` |  | ``
| 2078 | `863` |  | `_isDisposed = true;`
| 2078 | `864` |  | `}`
| 2239 | `865` |  | `}`
|  | `866` |  | ``
|  | `867` |  | `/// <summary>`
|  | `868` |  | `/// Finalizes an instance of the <see cref="Channel"/> class.`
|  | `869` |  | `/// </summary>`
|  | `870` |  | `~Channel()`
| 202 | `871` |  | `{`
| 101 | `872` |  | `Dispose(disposing: false);`
| 202 | `873` |  | `}`
|  | `874` |  | `}`
|  | `875` |  | `}`

# Methods/Properties

.ctor(Renci.SshNet.ISession,System.UInt32,System.UInt32,System.UInt32)
get_Session()
get_LocalChannelNumber()
get_LocalPacketSize()
get_LocalWindowSize()
get_RemoteChannelNumber()
set_RemoteChannelNumber(System.UInt32)
get_RemotePacketSize()
set_RemotePacketSize(System.UInt32)
get_RemoteWindowSize()
set_RemoteWindowSize(System.UInt32)
get_IsOpen()
get_IsConnected()
get_ConnectionInfo()
get_SessionSemaphore()
InitializeRemoteInfo(System.UInt32,System.UInt32,System.UInt32)
SendData(System.Byte[])
SendData(System.Byte[],System.Int32,System.Int32)
OnWindowAdjust(System.UInt32)
OnData(System.Byte[])
OnExtendedData(System.Byte[],System.UInt32)
OnEof()
OnClose()
OnRequest(Renci.SshNet.Messages.Connection.RequestInfo)
OnSuccess()
OnFailure()
RaiseExceptionEvent(System.Exception)
TrySendMessage(Renci.SshNet.Messages.Message)
SendMessage(Renci.SshNet.Messages.Message)
SendEof()
WaitOnHandle(System.Threading.WaitHandle)
Close()
OnDisconnected()
OnErrorOccured(System.Exception)
Session_Disconnected(System.Object,System.EventArgs)
OnChannelException(System.Exception)
Session_ErrorOccured(System.Object,Renci.SshNet.Common.ExceptionEventArgs)
OnChannelWindowAdjust(System.Object,Renci.SshNet.MessageEventArgs`1<Renci.SshNet.Messages.Connection.ChannelWindowAdjustMessage>)
OnChannelData(System.Object,Renci.SshNet.MessageEventArgs`1<Renci.SshNet.Messages.Connection.ChannelDataMessage>)
OnChannelExtendedData(System.Object,Renci.SshNet.MessageEventArgs`1<Renci.SshNet.Messages.Connection.ChannelExtendedDataMessage>)
OnChannelEof(System.Object,Renci.SshNet.MessageEventArgs`1<Renci.SshNet.Messages.Connection.ChannelEofMessage>)
OnChannelClose(System.Object,Renci.SshNet.MessageEventArgs`1<Renci.SshNet.Messages.Connection.ChannelCloseMessage>)
OnChannelRequest(System.Object,Renci.SshNet.MessageEventArgs`1<Renci.SshNet.Messages.Connection.ChannelRequestMessage>)
OnChannelSuccess(System.Object,Renci.SshNet.MessageEventArgs`1<Renci.SshNet.Messages.Connection.ChannelSuccessMessage>)
OnChannelFailure(System.Object,Renci.SshNet.MessageEventArgs`1<Renci.SshNet.Messages.Connection.ChannelFailureMessage>)
AdjustDataWindow(System.Byte[])
GetDataLengthThatCanBeSentInMessage(System.Int32)
CreateRemoteChannelInfoNotAvailableException()
CreateChannelClosedException()
Dispose()
Dispose(System.Boolean)
Finalize()