我尝试使用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);
......我没有错误/异常,但是:
该文件未上传
aSyncCallback
和uploadCallback
似乎无法正常工作
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:好的
答案 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
时,您不会等待它完成并立即断开连接。