随机获取Renci.SshNet.SftpClient.Connect并抛出SshConnectionException

时间:2019-02-04 20:23:32

标签: sftp ssh.net

我已经看到其他有关此错误的线程,但是我随机遇到此错误。在30个连接中,有12个出现此错误。试图了解原因以及可能的解决方案。

using (SftpClient client = new SftpClient(sftpHost, sftpPort, sftpUser, sftpPassword))
            {
                client.Connect();

引发此异常:Renci.SshNet.Common.SshConnectionException:服务器响应不包含SSH协议标识

2 个答案:

答案 0 :(得分:3)

这听起来似乎微不足道,但是我尝试了Renci.SshNet.Async程序包,它没有任何问题。以下可能是解决方案或替代解决方案出现问题的原因。

  1. Renci.SshNet.Async可能存在在特定环境或特定组合中出现的错误或问题。有些人在这里提到了相同的问题,没有解决办法https://github.com/sshnet/SSH.NET/issues/377
  2. 有些人遇到过同样的问题,并提到了解决方案,其中之一是重试 n Renci.SshNet : "server response does not contain ssh protocol identification"
  3. 问题不在于您的客户端,而是您的主机或多或少。它可以有很多事情或问题。
  4. 最后,我将尝试使用WinSCP,它也是.net(nuget)的公认库。我自己也尝试过,到目前为止从未遇到过任何问题。我建议您得到它,并尝试将其作为当前解决方案的替代方案,看看是否有帮助。如果WinSCP正常工作,则第1点有效;如果WinSCP遇到相同问题,则第3点有效。这样我们可以得出结论并缩小问题范围。

以下是WinSCP https://winscp.net/eng/docs/library_examples提供的示例。

我的测试示例为:

  

这只是一个操场示例,用于查看事物是否正在运行,在生产中使用时,请对其进行修改。还要感谢@MartinPrikry添加以下注释::如果您正确设置了SshHostKeyFingerprint,则不要设置GiveUpSecurityAndAcceptAnySshHostKey

public static int WinSCPListDirectory()
{
    try
    {
        var sessionOptions = new SessionOptions
        {
            Protocol = Protocol.Sftp,
            HostName = "xxx.xxx.xxx.xxx",
            UserName = "username",
            Password = "password",
            SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx",
            GiveUpSecurityAndAcceptAnySshHostKey = true
        };

        using (var session = new Session())
        {
            session.Open(sessionOptions);

            var directory = session.ListDirectory("/var/www");

            foreach (RemoteFileInfo fileInfo in directory.Files)
            {
                Console.WriteLine(
                    "{0} with size {1}, permissions {2} and last modification at {3}",
                    fileInfo.Name, fileInfo.Length, fileInfo.FilePermissions,
                    fileInfo.LastWriteTime);
            }
        }

        return 0;
    }
    catch (Exception e)
    {
        Console.WriteLine("Error: {0}", e);
        return 1;
    }
}

此示例应返回目录列表

相关链接:

答案 1 :(得分:0)

没有人知道这种行为的确切原因。

作为一种可能的解决方法,有人建议创建一个计数器循环以重试连接,表明它解决了他们的问题:

int attempts = 0;
do
{
    try
    {
        client.Connect();
    }
    catch (Renci.SshNet.Common.SshConnectionException e)
    {
        attempts++;
    }
} while (attempts < _connectiontRetryAttempts && !client.IsConnected);

另一建议是将IP地址添加到服务器上的hosts.allow文件中,以便您也可以沿该方向进行检查。

正如我所说,完全没有可能解释这种行为。