浏览代码

Fix and remove orphan threads when using port forwarding.

olegkap_cp 12 年之前
父节点
当前提交
badcf4052c

+ 12 - 0
Renci.SshClient/Renci.SshNet/Channels/Channel.cs

@@ -519,8 +519,18 @@ namespace Renci.SshNet.Channels
             }
         }
 
+        protected virtual void OnDisconnected()
+        {
+        }
+
+        protected virtual void OnErrorOccured(Exception exp)
+        {
+        }
+
         private void Session_Disconnected(object sender, EventArgs e)
         {
+            this.OnDisconnected();
+
             //  If objected is disposed or being disposed don't handle this event
             if (this._isDisposed)
                 return;
@@ -530,6 +540,8 @@ namespace Renci.SshNet.Channels
 
         private void Session_ErrorOccured(object sender, ExceptionEventArgs e)
         {
+            this.OnErrorOccured(e.Exception);
+
             //  If objected is disposed or being disposed don't handle this event
             if (this._isDisposed)
                 return;

+ 16 - 0
Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs

@@ -194,6 +194,22 @@ namespace Renci.SshNet.Channels
             this._channelEof.Set();
         }
 
+        protected override void OnErrorOccured(Exception exp)
+        {
+            base.OnErrorOccured(exp);
+
+            //  If error occured, no more data can be received
+            this._channelEof.Set();
+        }
+
+        protected override void OnDisconnected()
+        {
+            base.OnDisconnected();
+
+            //  If disconnected, no more data can be received
+            this._channelEof.Set();
+        }
+
         partial void ExecuteThread(Action action);
 
         partial void InternalSocketReceive(byte[] buffer, ref int read);

+ 13 - 0
Renci.SshClient/Renci.SshNet/ForwardedPortLocal.NET.cs

@@ -27,6 +27,9 @@ namespace Renci.SshNet
             this._listener = new TcpListener(ep);
             this._listener.Start();
 
+            this.Session.ErrorOccured += Session_ErrorOccured;
+            this.Session.Disconnected += Session_Disconnected;
+
             this._listenerTaskCompleted = new ManualResetEvent(false);
             this.ExecuteThread(() =>
             {
@@ -102,5 +105,15 @@ namespace Renci.SshNet
 
             this.IsStarted = false;
         }
+
+        private void Session_ErrorOccured(object sender, Common.ExceptionEventArgs e)
+        {
+            this._listener.Stop();
+        }
+
+        private void Session_Disconnected(object sender, EventArgs e)
+        {
+            this._listener.Stop();
+        }
     }
 }