使用 SSH.NET 恢复网络连接后自动恢复 SFTP 下载
Automatically resume SFTP download after network connection is restored with SSH.NET
我正在使用 SSH.NET 库来创建 SFTP 客户端。如果网络连接在此超时内再次可用,我需要恢复下载。我正在使用下面提到的方法,如许多示例所示。
PrivateKeyFile ObjPrivateKey = new PrivateKeyFile(keyStream);
PrivateKeyAuthenticationMethod ObjPrivateKeyAutentication = new PrivateKeyAuthenticationMethod(username, ObjPrivateKey);
var connectionInfo = new ConnectionInfo(hostAddress, port, username, ObjPrivateKeyAutentication);
try
{
using (var client = new SftpClient(connectionInfo))
{
client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(10);
client.Connect();
if (!client.IsConnected)
{
return false;
}
if (!client.Exists(source))
{
return false;
}
var fileName = Path.GetFileName(source);
using (var fs = new FileStream(destination + fileName, FileMode.Create))
{
client.DownloadFile(source, fs, printActionDel);
fs.Close();
returnState = true;
}
client.Disconnect();
client.Dispose();
}
}
我正在拔网线以中断下载并测试超时情况。虽然我在超时内再次启用互联网连接以恢复下载,但它没有恢复。我在这里做错了什么?请指教
如果您希望 SSH.NET 在 SftpClient.DownloadFile
内重新连接,则不会。
您必须自己实现重新连接和传输恢复。
PrivateKeyFile ObjPrivateKey = new PrivateKeyFile(keyStream);
PrivateKeyAuthenticationMethod ObjPrivateKeyAutentication =
new PrivateKeyAuthenticationMethod(username, ObjPrivateKey);
var connectionInfo =
new ConnectionInfo(hostAddress, port, username, ObjPrivateKeyAutentication);
bool retry = false;
do
{
bool retrying = retry;
retry = false;
using (var client = new SftpClient(connectionInfo))
{
client.Connect();
if (!client.Exists(source))
{
return false;
}
var fileName = Path.GetFileName(source);
var destinationFile = Path.Combine(destination, fileName);
try
{
var mode = retrying ? FileMode.Append : FileMode.Create;
using (var destinationStream = new FileStream(destinationFile, mode))
using (var sourceStream = client.Open(source, FileMode.Open))
{
sourceStream.Seek(destinationStream.Length, SeekOrigin.Begin);
// You can simply use sourceStream.CopyTo(destinationStream) here.
// But if you need to monitor download progress,
// you have to loop yourself.
byte[] buffer = new byte[81920];
int read;
ulong total = (ulong)destinationStream.Length;
while ((read = sourceStream.Read(buffer, 0, buffer.Length)) != 0)
{
destinationStream.Write(buffer, 0, read);
total = total + (ulong)read;
// report progress
printActionDel(total);
}
}
}
catch (SshException e)
{
retry = true;
}
}
}
while (retry);
或者使用另一个原生支持简历的 SFTP 库。
例如WinSCP .NET assembly does resume automatically in its Session.GetFiles
method.
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = hostAddress,
PortNumber = port,
UserName = username,
SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx...=",
SshPrivateKeyPath = keyPath
};
using (Session session = new Session())
{
session.FileTransferProgress += session_FileTransferProgress;
session.Open(sessionOptions);
var fileName = Path.GetFileName(source);
var destinationFile = Path.Combine(destination, fileName);
session.GetFiles(source, destinationFile).Check();
}
WinSCP GUI can generate an SFTP download code template 喜欢上面那个给你的。
(我是WinSCP的作者)
我正在使用 SSH.NET 库来创建 SFTP 客户端。如果网络连接在此超时内再次可用,我需要恢复下载。我正在使用下面提到的方法,如许多示例所示。
PrivateKeyFile ObjPrivateKey = new PrivateKeyFile(keyStream);
PrivateKeyAuthenticationMethod ObjPrivateKeyAutentication = new PrivateKeyAuthenticationMethod(username, ObjPrivateKey);
var connectionInfo = new ConnectionInfo(hostAddress, port, username, ObjPrivateKeyAutentication);
try
{
using (var client = new SftpClient(connectionInfo))
{
client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(10);
client.Connect();
if (!client.IsConnected)
{
return false;
}
if (!client.Exists(source))
{
return false;
}
var fileName = Path.GetFileName(source);
using (var fs = new FileStream(destination + fileName, FileMode.Create))
{
client.DownloadFile(source, fs, printActionDel);
fs.Close();
returnState = true;
}
client.Disconnect();
client.Dispose();
}
}
我正在拔网线以中断下载并测试超时情况。虽然我在超时内再次启用互联网连接以恢复下载,但它没有恢复。我在这里做错了什么?请指教
如果您希望 SSH.NET 在 SftpClient.DownloadFile
内重新连接,则不会。
您必须自己实现重新连接和传输恢复。
PrivateKeyFile ObjPrivateKey = new PrivateKeyFile(keyStream);
PrivateKeyAuthenticationMethod ObjPrivateKeyAutentication =
new PrivateKeyAuthenticationMethod(username, ObjPrivateKey);
var connectionInfo =
new ConnectionInfo(hostAddress, port, username, ObjPrivateKeyAutentication);
bool retry = false;
do
{
bool retrying = retry;
retry = false;
using (var client = new SftpClient(connectionInfo))
{
client.Connect();
if (!client.Exists(source))
{
return false;
}
var fileName = Path.GetFileName(source);
var destinationFile = Path.Combine(destination, fileName);
try
{
var mode = retrying ? FileMode.Append : FileMode.Create;
using (var destinationStream = new FileStream(destinationFile, mode))
using (var sourceStream = client.Open(source, FileMode.Open))
{
sourceStream.Seek(destinationStream.Length, SeekOrigin.Begin);
// You can simply use sourceStream.CopyTo(destinationStream) here.
// But if you need to monitor download progress,
// you have to loop yourself.
byte[] buffer = new byte[81920];
int read;
ulong total = (ulong)destinationStream.Length;
while ((read = sourceStream.Read(buffer, 0, buffer.Length)) != 0)
{
destinationStream.Write(buffer, 0, read);
total = total + (ulong)read;
// report progress
printActionDel(total);
}
}
}
catch (SshException e)
{
retry = true;
}
}
}
while (retry);
或者使用另一个原生支持简历的 SFTP 库。
例如WinSCP .NET assembly does resume automatically in its Session.GetFiles
method.
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = hostAddress,
PortNumber = port,
UserName = username,
SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx...=",
SshPrivateKeyPath = keyPath
};
using (Session session = new Session())
{
session.FileTransferProgress += session_FileTransferProgress;
session.Open(sessionOptions);
var fileName = Path.GetFileName(source);
var destinationFile = Path.Combine(destination, fileName);
session.GetFiles(source, destinationFile).Check();
}
WinSCP GUI can generate an SFTP download code template 喜欢上面那个给你的。
(我是WinSCP的作者)