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

连接:

  • 使用 SSH.NET 连接到 sFTP 站点似乎有效:SftpClientIsConnected 返回 true。

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

    Server's Host Key is Unknown

上传:

1) 使用SftpClientUploadFile方法:

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

...我收到 Renci.SshNet.Common.SftpPathNotFoundException:“系统找不到指定的路径。”

  • 我尝试过对路径进行硬编码 - 结果相同。
  • 我尝试过使用 SftpClientWorkingDirectory - 但这会转换为一串看起来像中文的字符,而且也不起作用。

2) 使用SftpClientBeginUploadFile方法:

    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"); 
    } 

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

使用上传文件:

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 Status: Connected to sshserv.CENSORED.com 2017-09-21 10:08:36 11252 1 Status: Retrieving directory listing... 2017-09-21 10:08:36 11252 1 Command: pwd 2017-09-21 10:08:36 11252 1 Response: Current directory is: "/SSHUsersPath" 2017-09-21 10:08:36 11252 1 Command: ls 2017-09-21 10:08:37 11252 1 Status: Listing directory /SSHUsersPath 2017-09-21 10:08:37 11252 1 Status: Directory listing of "/SSHUsersPath" successful 2017-09-21 10:08:58 11252 3 Status: Connecting to sshserv.CENSORED.com... 2017-09-21 10:08:58 11252 3 Response: fzSftp started, protocol_version=8 2017-09-21 10:08:58 11252 3 Command: open "[email protected]" 22 2017-09-21 10:08:59 11252 3 Command: Trust new Hostkey: Once 2017-09-21 10:09:00 11252 3 Command: Pass: ***** 2017-09-21 10:09:00 11252 3 Status: Connected to sshserv.CENSORED.com 2017-09-21 10:09:00 11252 3 Status: Starting upload of C:\File.txt 2017-09-21 10:09:00 11252 3 Command: cd "/SSHUsersPath" 2017-09-21 10:09:01 11252 3 Response: New directory is: "/SSHUsersPath" 2017-09-21 10:09:01 11252 3 Command: put "C:\File.txt" "File.txt" 2017-09-21 10:09:01 11252 3 Command: local:C:\File.txt => remote:/SSHUsersPath/File.txt 2017-09-21 10:09:01 11252 3 Status: File transfer successful, transferred 4 bytes in 1 second 2017-09-21 10:09:01 11252 3 Status: Retrieving directory listing of "/SSHUsersPath"... 2017-09-21 10:09:01 11252 3 Command: ls 2017-09-21 10:09:01 11252 3 Status: Listing directory /SSHUsersPath 2017-09-21 10:09:02 11252 3 Status: Directory listing of "/SSHUsersPath" successful 2017-09-21 10:09:17 11252 1 Status: Deleting "/SSHUsersPath/File.txt" 2017-09-21 10:09:17 11252 1 Command: rm "/SSHUsersPath/File.txt" 2017-09-21 10:09:18 11252 1 Response: rm /SSHUsersPath/File.txt: OK

请您参考如下方法:

主要问题是:

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时,您不会等待它完成并立即断开连接。


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!