使用SSH.NET上传到SFTP服务器失败并出现SftpPathNotFoundException:'系统找不到指定的路径。'

时间:2017-09-20 15:21:22

标签: c# .net ssh sftp ssh.net

我尝试使用Renci SSH.NET在SFTP上传文件。

连接:

  • 连接到sFTP站点使用SSH.NET ,似乎有效:SftpClient' s IsConnected返回true。

  • 但是,使用FileZilla 连接会触发此警告:

      

    服务器的主机密钥未知

上传

1)使用SftpClient' UploadFile方法:

    client.UploadFile(fileStream, "/Path/" + fileName, null);

...我收到Renci.SshNet.Common.SftpPathNotFoundException:'系统无法找到指定的路径。'

  • 我尝试过硬编码路径 - 结果相同。
  • 我已尝试使用SftpClient WorkingDirectory - 但这会转化为一串中文字符,但也无法使用。

2)使用SftpClient' BeginUploadFile方法:

    client.BeginUploadFile(fileStream, "/Path/" + fileName, asyncCallback, null, UpdateUploadProgress);

......我没有错误/异常,但是:

  • 该文件未上传

  • aSyncCallbackuploadCallback似乎无法正常工作

3)使用FileZilla,我可以上传得很好(使用与上面完全相同的目标路径:" /Path/Filename.txt")

我的代码:

    var connectionInfo = new ConnectionInfo(IpAddress,
                        Port,
                        UserName,
                        new PasswordAuthenticationMethod(UserName, Password),
                        new PrivateKeyAuthenticationMethod("rsa.key"));
            connectionInfo.Encoding = Encoding.Unicode;
            using (var client = new SftpClient(connectionInfo))
            {
                client.Connect();

                if (client.IsConnected)
                {
                    Console.WriteLine("SSH-client is connected");
                }
                var fileStream = new FileStream(FileMaker.GetFullyQualifiedPath(), FileMode.Open);
                client.BufferSize = 4 * 1024;
                string fileName = new FileMaker().GetFileName();
                //client.UploadFile(fileStream, "/Path/" + fileName, null);
                AsyncCallback asyncCallback = new AsyncCallback(NotifyUploadComplete);
                client.BeginUploadFile(fileStream, "/Path/" + fileName, asyncCallback, null, UpdateUploadProgress);
                client.Disconnect();
            }

回调处理程序:

    private void UpdateUploadProgress(ulong uploaded)
    {
        MainViewModel mainViewModel = (MainViewModel)System.Windows.Application.Current.FindResource("mainViewModel");
        mainViewModel.UploadProgress = uploaded;
    }

    private void NotifyUploadComplete(IAsyncResult result)
    {
        MessageBox.Show("File uploaded.", "File uploaded");
    }

更新: 我做了一个最小的例子并测试了它(相同的结果)。

使用UploadFile:

var connectionInfo = new ConnectionInfo(IpAddress,
            Port,
            UserName,
            new PasswordAuthenticationMethod(UserName, Password),
            new PrivateKeyAuthenticationMethod("rsa.key"));
connectionInfo.Encoding = Encoding.Unicode;
using (var client = new SftpClient(connectionInfo))
{
    client.Connect();

    if (client.IsConnected)
    {
        Console.WriteLine("SSH-client is connected");
    }
    var fileStream = new FileStream(@"C:\File.txt", FileMode.Open);
    client.BufferSize = 4 * 1024;
    client.UploadFile(fileStream, "/SSHUsersPath/File.txt", null);
    //AsyncCallback asyncCallback = new AsyncCallback(NotifyUploadComplete);
    //client.BeginUploadFile(fileStream, "/SSHUsersPath/File.txt", asyncCallback, null, UpdateUploadProgress);
    client.Disconnect();
}

这里是请求的FileZilla日志文件的摘录:

  

2017-09-21 10:08:36 11252 1状态:已连接至   sshserv.CENSORED.com 2017-09-21 10:08:36 11252 1状态:   检索目录列表... 2017-09-21 10:08:36 11252 1命令:   pwd 2017-09-21 10:08:36 11252 1回复:当前目录是:   " / SSHUsersPath" 2017-09-21 10:08:36 11252 1命令:ls 2017-09-21   10:08:37 11252 1状态:房源目录/ SSHUsersPath 2017-09-21   10:08:37 11252 1状态:" / SSHUsersPath"的目录列表   成功2017-09-21 10:08:58 11252 3状态:正在连接   sshserv.CENSORED.com ... 2017-09-21 10:08:58 11252 3回复:   fzSftp启动,protocol_version = 8 2017-09-21 10:08:58 11252 3   命令:打开" CENSORED@sshserv.CENSORED.com" 2017 2017-21-21   10:08:59 11252 3命令:相信新的Hostkey:一次2017-09-21 10:09:00   11252 3命令:传球:***** 2017-09-21 10:09:00 11252 3状态:   连接到sshserv.CENSORED.com 2017-09-21 10:09:00 11252 3   状态:开始上传C:\ File.txt 2017-09-21 10:09:00 11252 3   命令:cd" / SSHUsersPath" 2017-09-21 10:09:01 11252 3回复:新的   目录是:" / SSHUsersPath" 2017-09-21 10:09:01 11252 3命令:放   " C:\ FILE.TXT" " FILE.TXT" 2017-09-21 10:09:01 11252 3命令:   local:C:\ File.txt => remote:/SSHUsersPath/File.txt 2017-09-21 10:09:01   11252 3状态:文件传输成功,传输4个字节,1   second 2017-09-21 10:09:01 11252 3状态:正在检索目录   列表" / SSHUsersPath" ... 2017-09-21 10:09:01 11252 3命令:ls   2017-09-21 10:09:01 11252 3状态:列表目录/ SSHUsersPath   2017-09-21 10:09:02 11252 3状态:商家信息的目录列表   " / SSHUsersPath"成功2017-09-21 10:09:17 11252 1状态:   删除" /SSHUsersPath/File.txt" 2017-09-21 10:09:17 11252 1命令:   rm" /SSHUsersPath/File.txt" 2017-09-21 10:09:18 11252 1回复:rm   /SSHUsersPath/File.txt:好的

1 个答案:

答案 0 :(得分:1)

主要问题是:

connectionInfo.Encoding = Encoding.Unicode;

Encoding.Unicode是UTF-16。没有SFTP服务器将处理UTF-16编码的文件名。 SFTP服务器应使用UTF-8。因此,SSH.NET默认为Encoding.UTF8。如果使用UTF-8,服务器会破坏文件名中的非ascii字符(.Encoding与文件名有关,而不是文件内容),必须是因为SFTP已损坏并使用了一些传统编码。但可以肯定的是,它不是UTF-16。它只是一些ISO*编码或Windows-*编码。

另一个问题是,当您使用BeginUploadFile时,您不会等待它完成并立即断开连接。