【问题标题】:How do I decrease the ssh.net timeout when my ssh client disconnects from the ssh server?当我的 ssh 客户端与 ssh 服务器断开连接时,如何减少 ssh.net 超时?
【发布时间】:2016-03-25 04:05:44
【问题描述】:

我使用 ssh.net 用 C# 编写了一个小程序,它连接到 SSH 服务器,进行一些更改,并在 SSH 服务器上重新启动 SSHD 服务。

不幸的是,SSH 服务器在一个缓慢的嵌入式系统上运行,并且 SSHD 服务没有足够快的速度重新启动,无法无​​缝地执行此操作(无需断开客户端连接)。 SSH 服务实际上需要大约一分钟才能重新启动。这很好。

我的代码如下所示:

Console.WriteLine("Restarting SSHD service on modem...");

try
{
    using (var client = new SshClient(IPAddress, "root", "PASSWORD"))
    {
        client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(10);
        client.Connect();

        client.RunCommand("service sshd restart");

        client.Disconnect();
    }
}
catch (System.Net.Sockets.SocketException)
{
    //We got disconnected because we just restarted the sshd service
    //This is expected
    Console.WriteLine("\tSuccess");
}
catch
{
    //We got disconnected for some other reason
    Console.WriteLine("\tIt appears there was a problem restarting the sshd service");
}

我遇到的问题是 ssh 客户端需要一分钟甚至更长的时间才能确定 SSH 服务器不再响应,并抛出 System.Net.Sockets.SocketException。有什么办法可以缩短这个超时时间?我不希望它重新连接 - 我只是希望它尽快抛出异常。 这是某种 ssh.net 特定的超时值,还是 System.Net.Sockets 超时?

【问题讨论】:

  • 我不确定远程服务器是什么,我有“服务重启”的 Linux 框不会终止现有的客户端连接,您是否设置了 TCPKeepAlive 或 ServerAliveInterval 等以确保连接不会由于命令缓慢而超时?我的印象是,如果没有设置 keepalive,连接将在大约 1 分钟内被切断,这与您所看到的相符。
  • 我在我的 SshClient 对象中发现的唯一听起来相关的值是 client.KeepAliveInterval 和 client.ConnectionInfo.RetryAttempts。 KeepAliveInterval 听起来像是 TCPKeepAlive 的另一个名称,所以我尝试将其设置为 10 秒,但没有任何效果。我还将 RetryAttempts 设置为 1,但这也没有效果 - 抛出异常仍然需要一分钟多的时间。还有其他地方可以设置 TCPKeepAlive 和 ServerAliveInterval 吗?
  • 该链接处理配置 ssh 服务器以向客户端发送 keepalive 消息,以便会话不会中断。我希望会话更快地下降。我也无法修改 ssh 服务器的 sshd_config,因为我要处理数百个 SSH 服务器,并且提前修改所有这些服务器的 sshd_config 是不可行的。
  • All I want is to send the "service sshd restart" command to the server, and disconnect as quickly as possible - 你可以做 "service sshd restart &" 或者,取决于 SSH 服务器上的发行版,可能是 "service sshd restart >/dev/null 2>&1 &"

标签: c# sockets ssh ssh.net


【解决方案1】:

感谢Hang的建议,下面的代码已经解决了问题:

Console.WriteLine("Restarting SSHD service on modem...");

try
{
    var client = new SshClient(IPAddress, "root", "PASSWORD")
    client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(10);
    client.Connect();

    client.RunCommand("service sshd restart >/dev/null 2>&1 &");
    Console.WriteLine("\tSuccess");
}
catch (System.Net.Sockets.SocketException)
{
    //We got disconnected because we just restarted the sshd service
    //This is expected
    Console.WriteLine("\tSuccess");
}
catch
{
    //We got disconnected for some other reason
    Console.WriteLine("\tIt appears there was a problem restarting the sshd service");
}

需要注意的是:

  • RunCommand 行现在使用 >/dev/null 2>&1 去除 stdout 和 stderr
  • RunCommand 行现在使用 & 在后台运行命令
  • try 块现在包含一个Console.WriteLine("\tSuccess");,因为这是RunCommand() 最可能的结果 - 事实上它会继续运行而不是抛出任何异常
  • 不再有 client.Disconnect()using 语句,因此没有任何尝试与 ssh 服务器断开连接 - 代码继续运行

这在我的情况下有效的原因是因为我的程序在此之后基本上没有做任何其他事情 - 它只是退出。其他人可能希望等到 SshClient 再次可用,然后正确断开连接以清理和释放资源。

【讨论】:

    猜你喜欢
    • 2013-08-25
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 2017-12-28
    • 2012-10-11
    • 2014-08-22
    相关资源
    最近更新 更多