随机获取Renci.SshNet.SftpClient.Connect时抛出SshConnectionException异常

11

我看到有关于这个错误的其他帖子,但是我随机地遇到了这个错误。在30次连接中,有12次出现了这个错误。我试图理解为什么会出现这种情况,以及可能的解决方案。

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

抛出此异常:

Renci.SshNet.Common.SshConnectionException:服务器响应不包含SSH协议标识


1
源代码来看,这可能是一般通信错误,可能是超时或连接中断。您能否使用常规的SSH客户端连接到服务器?您的连接稳定吗? - orhtej2
最糟糕的部分是我完全无法预测地遇到这个错误,有时候只有10%的概率,有时候则有50%的概率。 - Alex Gordon
2
@l--''''''---------'''''''''''' 这听起来像是网络问题。如果您使用putty/sftp或其他ssh/sftp客户端,结果如何?如果您连续进行ping(至少一个小时),会显示什么? - tukan
2
嗅探器指示良好和不良响应之间的差异是什么?SSH是使用TCP端口22的安全外壳连接。加密中可能出现问题,但如果没有看到嗅探器数据,就不确定。 - jdweng
我认为错误应该是由ftp服务器引起的(可能很忙等)。请检查服务器的最大连接设置。 - Gokhan
2个回答

8
这听起来可能很琐碎,但我尝试了Renci.SshNet.Async软件包,并且没有出现任何问题。以下可能是问题原因和解决方案或替代方案。
  1. Renci.SshNet.Async可能存在错误或问题,这些错误或问题出现在特定环境或特定组合中。一些人在此处提到了相同的问题,但没有解决方案https://github.com/sshnet/SSH.NET/issues/377
  2. 一些人遇到了相同的问题并提出了解决方案之一,即重试nRenci.SshNet:"服务器响应不包含ssh协议标识"
  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
没有人确切知道这种行为的原因。作为可能的解决方案,一些人建议创建一个计数器循环以重试连接,并表示这解决了他们的问题。
int attempts = 0;
do
{
    try
    {
        client.Connect();
    }
    catch (Renci.SshNet.Common.SshConnectionException e)
    {
        attempts++;
    }
} while (attempts < _connectiontRetryAttempts && !client.IsConnected);

另一个建议是将IP地址添加到服务器的hosts.allow文件中,这样您也可以在该方向上进行检查。
正如我所说,总体行为没有可能的解释。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接