From 2c435ec12c11a7f43f3cdf575eb41839d96daa02 Mon Sep 17 00:00:00 2001 From: olegkap_cp Date: Thu, 11 Nov 2010 19:36:00 +0000 Subject: [PATCH] Fix remote port forwarding socket read functionality --- .../Channels/ChannelForwardedTcpip.cs | 40 +++++++++++++++---- Renci.SshClient/Renci.SshClient/SshClient.cs | 11 +++++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelForwardedTcpip.cs b/Renci.SshClient/Renci.SshClient/Channels/ChannelForwardedTcpip.cs index f0ebbd9a..538b57a2 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/ChannelForwardedTcpip.cs +++ b/Renci.SshClient/Renci.SshClient/Channels/ChannelForwardedTcpip.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Net; using System.Net.Sockets; +using System.Threading; using Renci.SshClient.Common; using Renci.SshClient.Messages.Connection; @@ -67,18 +68,41 @@ namespace Renci.SshClient.Channels } // Start reading data from the port and send to channel - using (var ns = new NetworkStream(this._socket)) + while (this._socket.Connected || this.IsConnected) { - do + try { - var read = ns.Read(buffer, 0, buffer.Length); - this.SendMessage(new ChannelDataMessage + var read = this._socket.Receive(buffer); + if (read > 0) { - LocalChannelNumber = this.RemoteChannelNumber, - Data = buffer.Take(read).GetSshString(), - }); + this.SendMessage(new ChannelDataMessage + { + LocalChannelNumber = this.RemoteChannelNumber, + Data = buffer.Take(read).GetSshString(), + }); + } + else + { + // Zero bytes received when remote host shuts down the connection + break; + } + } + catch (SocketException exp) + { + if (exp.SocketErrorCode == SocketError.WouldBlock || + exp.SocketErrorCode == SocketError.IOPending || + exp.SocketErrorCode == SocketError.NoBufferSpaceAvailable) + { + // socket buffer is probably empty, wait and try again + Thread.Sleep(30); + } + else if (exp.SocketErrorCode == SocketError.ConnectionAborted) + { + break; + } + else + throw; // throw any other error } - while (ns.DataAvailable); } this.SendMessage(new ChannelEofMessage diff --git a/Renci.SshClient/Renci.SshClient/SshClient.cs b/Renci.SshClient/Renci.SshClient/SshClient.cs index 71c463ff..4a0aabe7 100644 --- a/Renci.SshClient/Renci.SshClient/SshClient.cs +++ b/Renci.SshClient/Renci.SshClient/SshClient.cs @@ -11,6 +11,17 @@ namespace Renci.SshClient public ConnectionInfo ConnectionInfo { get; private set; } + public bool IsConnected + { + get + { + if (this._session == null) + return false; + else + return this._session.IsConnected; + } + } + private Sftp _sftp; /// /// Gets the shell.