编辑
2025-10-10
C#
00

目录

安装
基本用法
连接到 SSH 服务器
2.2 执行远程命令
3. 高级用法
3.1 使用密钥认证
3.2 SFTP 文件传输
上传
下载
3.3 端口转发
3.4 执行多个命令
3.5 使用 SCP 传输文件
3.6 异步操作
3.7 处理大文件传输
4. 错误处理和最佳实践
4.1 使用 try-catch 块
4.2 使用 using 语句
4.3 检查连接状态
4.4 设置超时
5. 结论

SSH.NET 是一个功能丰富的 .NET SSH 客户端库,它提供了一个简单而强大的 API 来执行各种 SSH 操作。本文将详细介绍 SSH.NET 的使用方法,并提供多个实用的例子。

安装

首先,通过 NuGet 包管理器安装 SSH.NET

C#
Install-Package SSH.NET

image.png

基本用法

连接到 SSH 服务器

C#
using Renci.SshNet; using System; class Program { static void Main(string[] args) { string host = "127.0.0.1"; string username = "rick"; string password = "123456"; using (var client = new SshClient(host, username, password)) { try { client.Connect(); Console.WriteLine("Connected to the SSH server!"); // 执行其他操作... client.Disconnect(); Console.WriteLine("Disconnected from the SSH server."); } catch (Exception ex) { Console.WriteLine($"An error occurred: {ex.Message}"); } } } }

image.png

2.2 执行远程命令

C#
static void Main(string[] args) { string host = "127.0.0.1"; string username = "trueideal"; string password = "123456"; using (var client = new SshClient(host, username, password)) { try { client.Connect(); Console.WriteLine("Connected to the SSH server!"); using (var cmd = client.CreateCommand("ls -l")) { var result = cmd.Execute(); Console.WriteLine("Command output:"); Console.WriteLine(result); } client.Disconnect(); Console.WriteLine("Disconnected from the SSH server."); } catch (Exception ex) { Console.WriteLine($"An error occurred: {ex.Message}"); } } }

image.png

3. 高级用法

3.1 使用密钥认证

C#
using Renci.SshNet; using System.IO; class Program { static void Main(string[] args) { string host = "127.0.0.1; string username = "rick"; string privateKeyFile = @"D:\private_key.pem"; using (var stream = new FileStream(privateKeyFile, FileMode.Open, FileAccess.Read)) { var privateKeyFile = new PrivateKeyFile(stream); var privateKeyFiles = new[] { privateKeyFile }; using (var client = new SshClient(host, username, privateKeyFiles)) { client.Connect(); Console.WriteLine("Connected using private key authentication!"); // 执行其他操作... client.Disconnect(); } } } }

3.2 SFTP 文件传输

上传

C#
static void Main(string[] args) { // SFTP服务器的连接参数 string host = "127.0.0.1"; // 服务器地址(本地主机) string username = "trueideal"; // SFTP用户名 string password = "123456"; // SFTP密码 // 创建SFTP客户端实例并确保资源正确释放 using (var client = new SftpClient(host, username, password)) { try { // 尝试连接到SFTP服务器 client.Connect(); Console.WriteLine("已成功连接到SFTP服务器!"); // 列出当前用户主目录下的文件 // 使用 "." 表示当前目录,这通常比使用 "/" 根目录有更高的成功率 var files = client.ListDirectory("."); foreach (var file in files) { // 打印每个文件的名称和大小 Console.WriteLine($"{file.Name} - {file.Length} 字节"); } // 上传文件到SFTP服务器 // 打开本地文件并上传到用户的主目录 using (var fileStream = new FileStream(@"D:\Archive.csv", FileMode.Open)) { // './Archive.csv' 表示上传到当前用户的主目录 client.UploadFile(fileStream, "./Archive.csv"); } // 完成操作后断开连接 client.Disconnect(); } catch (Exception ex) { // 错误处理 Console.WriteLine($"发生错误: {ex.Message}"); // 输出详细的错误信息,包括堆栈跟踪等 Console.WriteLine($"错误详情: {ex}"); } } }

image.png

下载

C#
static void Main(string[] args) { // SFTP服务器连接参数 string host = "127.0.0.1"; string username = "trueideal"; string password = "123456"; using (var client = new SftpClient(host, username, password)) { try { // 连接到SFTP服务器 client.Connect(); Console.WriteLine("已成功连接到SFTP服务器!"); // 列出服务器上可供下载的文件 Console.WriteLine("\n当前目录下的文件列表:"); var files = client.ListDirectory("."); foreach (var file in files) { Console.WriteLine($"{file.Name} - {file.Length} 字节"); } // 下载文件示例1:下载到指定路径 string remoteFile = "./Archive.csv"; // SFTP服务器上的文件路径 string localPath = @"D:\Downloads\"; // 本地保存目录 string localFile = Path.Combine(localPath, "Downloaded_Archive.csv"); // 本地完整文件路径 // 确保本地目录存在 Directory.CreateDirectory(localPath); // DownloadFile方法 using (var fileStream = File.Create(localFile)) { Console.WriteLine($"\n开始下载文件: {remoteFile}"); client.DownloadFile(remoteFile, fileStream); Console.WriteLine($"文件已下载到: {localFile}"); } // 断开连接 client.Disconnect(); Console.WriteLine("已断开与SFTP服务器的连接。"); } catch (Exception ex) { // 错误处理 Console.WriteLine($"\n发生错误: {ex.Message}"); if (ex is FileNotFoundException) { Console.WriteLine("远程文件不存在!"); } else if (ex is DirectoryNotFoundException) { Console.WriteLine("本地目录不存在!"); } else if (ex is IOException) { Console.WriteLine("文件读写错误!"); } Console.WriteLine($"详细错误信息: {ex}"); } } Console.WriteLine("\n按任意键退出..."); Console.ReadKey(); }

3.3 端口转发

C#
static void Main(string[] args) { // SFTP服务器连接参数 string host = "127.0.0.1"; string username = "trueideal"; string password = "123456"; using (var client = new SshClient(host, username, password)) { try { client.Connect(); Console.WriteLine("Connected to SSH server!"); // 本地端口转发 var forwardedPort = new ForwardedPortLocal("127.0.0.1", 8080, "remote.example.com", 80); client.AddForwardedPort(forwardedPort); forwardedPort.Start(); Console.WriteLine("Port forwarding started. Press any key to stop..."); Console.ReadKey(); forwardedPort.Stop(); client.Disconnect(); } catch (Exception ex) { Console.WriteLine($"An error occurred: {ex.Message}"); } } }
  • 将本地端口的连接转发到远程服务器
  • 访问localhost:8080实际上访问的是remote.example.com:80

3.4 执行多个命令

C#
static void Main(string[] args) { // SFTP服务器连接参数 string host = "127.0.0.1"; string username = "trueideal"; string password = "123456"; using (var client = new SshClient(host, username, password)) { try { client.Connect(); Console.WriteLine("Connected to SSH server!"); // 执行多个命令 using (var shellStream = client.CreateShellStream("xterm", 80, 24, 800, 600, 1024)) { shellStream.WriteLine("cd /tmp"); shellStream.WriteLine("mkdir test_folder"); shellStream.WriteLine("ls -l"); shellStream.WriteLine("exit"); string line; while ((line = shellStream.ReadLine()) != null) { Console.WriteLine(line); } } client.Disconnect(); } catch (Exception ex) { Console.WriteLine($"An error occurred: {ex.Message}"); } } }

image.png

3.5 使用 SCP 传输文件

C#
static void Main(string[] args) { // SFTP服务器连接参数 string host = "127.0.0.1"; string username = "trueideal"; string password = "123456"; using (var client = new ScpClient(host, username, password)) { try { client.Connect(); Console.WriteLine("Connected to SCP server!"); // 上传文件 client.Upload(new FileInfo(@"C:\local\file.txt"), "/remote/path/file.txt"); Console.WriteLine("File uploaded successfully!"); // 下载文件 client.Download("/remote/path/file.txt", new FileInfo(@"C:\local\downloaded_file.txt")); Console.WriteLine("File downloaded successfully!"); client.Disconnect(); } catch (Exception ex) { Console.WriteLine($"An error occurred: {ex.Message}"); } } }

3.6 异步操作

C#
static async Task Main(string[] args) { // SFTP服务器连接参数 string host = "127.0.0.1"; string username = "trueideal"; string password = "123456"; using (var client = new SshClient(host, username, password)) { try { var timeout = TimeSpan.FromSeconds(30); using (var cts = new CancellationTokenSource(timeout)) { await client.ConnectAsync(cts.Token); Console.WriteLine("Connected to SSH server!"); var command = client.CreateCommand("ls -l"); // 异步执行命令 await command.ExecuteAsync(cts.Token); // 命令执行完成后,可以通过Result属性获取输出 string result = command.Result; Console.WriteLine($"Command output: {result}"); // 如果需要错误输出 if (!string.IsNullOrEmpty(command.Error)) { Console.WriteLine($"Error output: {command.Error}"); } // 如果需要获取退出状态码 int? exitStatus = command.ExitStatus; Console.WriteLine($"Exit status: {exitStatus}"); } client.Disconnect(); } catch (OperationCanceledException) { Console.WriteLine("Operation timed out"); } catch (Exception ex) { Console.WriteLine($"An error occurred: {ex.Message}"); } finally { if (client.IsConnected) { client.Disconnect(); } } } }

image.png

3.7 处理大文件传输

C#
static async Task Main(string[] args) { // SFTP服务器连接参数 string host = "127.0.0.1"; string username = "trueideal"; string password = "123456"; using (var client = new SftpClient(host, username, password)) { try { client.Connect(); Console.WriteLine("Connected to SFTP server!"); // 上传大文件 using (var fileStream = new FileStream(@"C:\local\large_file.zip", FileMode.Open)) { client.BufferSize = 4 * 1024; // 设置缓冲区大小为4K client.UploadFile(fileStream, "/remote/path/large_file.zip", true, (uploaded) => { Console.WriteLine($"Uploaded: {uploaded} bytes"); }); } Console.WriteLine("Large file uploaded successfully!"); client.Disconnect(); } catch (Exception ex) { Console.WriteLine($"An error occurred: {ex.Message}"); } } }

4. 错误处理和最佳实践

4.1 使用 try-catch 块

始终使用 try-catch 块来处理可能出现的异常:

C#
try { using (var client = new SshClient(host, username, password)) { client.Connect(); // 执行操作... client.Disconnect(); } } catch (Renci.SshNet.Common.SshAuthenticationException ex) { Console.WriteLine($"Authentication failed: {ex.Message}"); } catch (Renci.SshNet.Common.SshConnectionException ex) { Console.WriteLine($"Connection failed: {ex.Message}"); } catch (Exception ex) { Console.WriteLine($"An unexpected error occurred: {ex.Message}"); }

4.2 使用 using 语句

总是使用 using 语句来确保资源被正确释放:

C#
using (var client = new SshClient(host, username, password)) { // 使用客户端... }

4.3 检查连接状态

在执行操作之前,始终检查连接状态:

C#
if (!client.IsConnected) { client.Connect(); }

4.4 设置超时

为长时间运行的操作设置超时:

C#
client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(30);

5. 结论

SSH.NET 是一个功能强大且易于使用的 SSH 客户端库。它提供了广泛的功能,从基本的 SSH 连接和命令执行到高级的文件传输和端口转发。通过本文提供的示例,你应该能够处理大多数 SSH 相关的任务。

使用 SSH.NET 可以极大地简化在 C# 应用程序中实现 SSH 功能的过程。无论是系统管理、自动化部署还是远程数据处理,SSH.NET 都是一个excellent选择。

在使用 SSH.NET 时,请记住正确处理异常,并考虑网络连接的不稳定性。对于需要处理大文件或执行长时间运行的操作的情况,可能需要考虑使用异步方法和进度回调。

希望这篇文章对你有所帮助,祝你在 C# 开发中使用 SSH.NET 愉快!

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!