我使用 SSH.NET 在 .Net-Applications 中创建 SSH 隧道。在我的 ConsoleApplication / Windows-Service 中,这个库按预期工作。
现在我编写了一个 WPF 应用程序,它创建了一个 SSH 隧道来远程访问 MySQL 数据库。我可以访问数据库并执行我的 SQL 语句就好了。
但是,如果我在与数据库断开连接后尝试关闭隧道,我首先会收到一个 SocketException: 10004 A blocking operation was interrupted by call WSACancelBlockingCall 然后还有几个异常:
- SocketException: 10053 主机中的软件停止了已建立的连接,可能是由于数据传输超时或协议错误。
- Renci.SshNet.Common.SshConnectionException: Bad packet length XXX (XXX 是一个随机整数)
- Renci.SshNet.Common.SshConnectionException:客户端未连接。
我使用以下代码打开/关闭隧道:
public class SSHTunnelBuilder
{
private SshClient client;
private ForwardedPort port;
public SSHTunnelBuilder()
{
}
public void CloseTunnel()
{
if (this.port != null && this.port.IsStarted)
{
this.port.Stop();
}
if (this.client != null && this.client.ForwardedPorts.Contains(this.port))
{
this.client.RemoveForwardedPort(this.port);
}
this.port = null;
if (this.client != null)
{
if (this.client.IsConnected)
{
this.client.Disconnect();
}
this.client.Dispose();
this.client = null;
}
}
public void OpenTunnel()
{
if (this.client == null)
{
this.client = new SshClient("host", "usr", "pwd");
}
if (!this.client.IsConnected)
{
this.client.Connect();
}
if (this.port == null)
{
this.port = new ForwardedPortLocal("XXX.XXX.XXX.XXX", 10000, "YYY.YYY.YYY.YYY", 3306);
}
if (!this.client.ForwardedPorts.Contains(this.port))
{
this.client.AddForwardedPort(this.port);
}
if (!this.port.IsStarted)
{
this.port.Start();
}
}
}
并且 SSHTunnelBuilder 在这样的 TASK 中使用:
private void SomeMethod()
{
Task.Factory.StartNew(
new Action(() =>
{
SSHTunnelBuilder ssh = new SSHTunnelBuilder();
try
{
ssh.OpenTunnel();
// Do something
ssh.CloseTunnel();
ssh.Dispose();
ssh = null;
}
catch (Exception e)
{
ssh.CloseTunnel();
ssh.Dispose();
ssh = null;
}
}));
}
有人可以向我解释如何摆脱这些异常吗?