- 桌面应用
- 网络
【免费下载链接】mRemoteNG
mRemoteNG is the next generation of mRemote, open source, tabbed, multi-protocol, remote connections manager.
mRemoteNG 内置了SSH File Transfer(SSH 文件传输)工具,允许你通过加密的 SSH 隧道,使用SFTP或SCP协议将本地文件安全地上传到远程主机。本文将结合官方用户手册 ssh_file_transfer.rst 与该功能在仓库中的插件源码(mRemoteNG.Plugins.SshTransfer),系统讲解该工具的前置条件、每个配置项的含义与默认值、完整操作流程、底层实现原理,以及常见错误的排查方法。读完本文,你将能够熟练使用 mRemoteNG 完成一次安全可靠的 SSH 文件上传,并能独立定位和解决大多数传输失败问题。
一、功能概览:SFTP 与 SCP 二选一
SSH File Transfer 的核心能力是:在一条加密的 SSH 连接之上,把本地文件传送到远程主机的指定目录。它支持两种底层协议:
- SFTP(SSH File Transfer Protocol):基于 SSH 会话的完整文件传输协议,支持文件属性操作、断点续传语义等,现代 Linux/Unix 系统默认开启(
sftp-server子系统)。 - SCP(Secure Copy):基于 SSH 通道的简化复制协议,使用
scp命令的协议语义,兼容性极广,几乎所有带 SSH 服务的主机都可用。
在源码中,这两种协议被定义为一个枚举类型,见 SshTransferProtocol.cs:
internal enum SshTransferProtocol { Scp = 0, Sftp = 1, }UI 面板上通过两个单选按钮(SCP/SFTP)让用户二选一,SCP 为默认选中项(见 SshTransferControl.cs 中_radProtScp.Checked = true的初始化)。
从实现上看,该工具是一个独立插件(mRp.SshTransfer.dll),通过IToolWindowPlugin接口注册为 mRemoteNG 主程序的一个工具窗口,运行时由主程序从插件目录动态加载,而不是硬编码在主程序集中(参见 README.plugins.md 与 SshTransferPlugin.cs)。
二、前置条件(Prerequisites)
在开始传输之前,请确认以下三个条件全部满足:
- 远程主机运行着 SSH 服务,并监听在一个可达的网络端口上(默认 22 端口)。SSH 服务是 SFTP/SCP 共同依赖的底层通道,没有它一切无从谈起。
- 拥有可用的用户名和密码,用于登录远程主机。当前工具通过用户名 + 密码完成认证(源码中
SecureTransferService构造参数即host, user, password, port)。 - 远程文件系统上存在可写目录,用于放置传输过来的文件。如果目标路径不可写,传输会因权限问题失败(对应下文"SSH background transfer failed!" 错误)。
三、打开 SSH 文件传输工具
在 mRemoteNG 主界面中,通过菜单Tools --> SSH File Transfer打开该工具。
从插件源码看,这一菜单项正是由 SshTransferPlugin.cs 的ToolWindowRegistration注册的,它声明了:
MenuText/WindowTitle:均为 "SSH File Transfer";ShowAsDocument = true:以文档(标签页)形式在主界面中打开;PanelName = "General":归属通用面板分组;RequiresConnectionSelection = false:不强制要求先选中某个连接;SortOrder = 150:决定在菜单/面板中的排列顺序;Icon:使用资源中的SyncArrow_16x图标(传输箭头)。
打开后,面板会作为一个新标签页出现在 mRemoteNG 内部,包含"连接信息"(Connection)和"文件"(Files)两个分组,以及底部的传输进度条。面板布局在SshTransferControl.InitializeComponent()中构建:连接分组包含 Host / Port / User / Password / Protocol 五个输入项,文件分组包含 Local File / Remote File 输入框、"Browse" 按钮和 "Transfer" 按钮。
四、配置项详解
要完成一次传输,面板中的每个配置项都需要正确填写。各选项的含义、默认值与源码对应关系如下:
| 配置项 | 说明 | 默认值 / 备注(源码依据) |
|---|---|---|
| Host | 要连接的远程主机,可以是 DNS 名称或 IP 地址 | 空。若从连接预填充,取连接的Hostname |
| Port | 远程主机监听 SSH/SFTP/SCP 流量的端口 | 文本框默认22(_txtPort.Text = "22");从连接预填充时取连接的Port,无端口则回退为 22 |
| User | 用于登录远程主机的账户名 | 空。从连接预填充时取Username,若存在域信息则组合为域\用户名 |
| Password | 用于登录远程主机的账户密码 | 空。输入框设置了UseSystemPasswordChar = true,输入时以掩码显示 |
| Protocol | 通信使用的协议:SCP 或 SFTP | 默认选中SCP |
| Local File | 要从本地主机传输的文件路径 | 空。可通过Browse按钮打开文件选择对话框(OpenFileDialog,过滤器为所有文件)填充 |
| Remote File | 文件在远程主机上的目标路径(含文件名),例如/home/John/Documents | 空。需手动键入 |
这里有两个容易忽略但很有用的细节(均来自 SshTransferControl.cs 源码):
- 远程路径以
/或\结尾时自动补全文件名:在点击 Transfer 前的校验逻辑AllFieldsSet()中,如果 Remote File 以/或\结尾,工具会自动把本地文件的文件名(Path.GetFileName)追加到远程路径后面。也就是说,你可以在 Remote File 里只填目录(如/home/John/Documents/),工具会自动变成/home/John/Documents/文件名。 - 密码可留空但需二次确认:如果密码为空,工具会弹出确认框询问 "Password is empty. Continue?",选择"否"则取消传输(适用于配置了免密认证或密钥已就位的场景)。
此外,所有标签文本均支持通过插件资源机制做本地化(ApplyLanguage()调用Resources.GetString读取多语言资源,带英文 fallback),因此界面文案在不同语言环境下会自适应显示。
从已有连接快速预填充
SshTransferPlugin.OnBeforeShow会在面板显示前调用PopulateFromConnection(connection),其逻辑是:如果当前在连接树中选中了一个 SSH 类型的连接,则自动把该连接的主机名、用户名、密码、端口带入面板,并自动勾选 SCP 协议(协议 ID 为ssh、ssh1或ssh2时)。这样你就无需重复输入凭据,只需补上本地文件和远程路径即可发起传输。若域(Domain)不为空,用户名会按域\用户名格式拼接(见BuildUserName方法)。
五、使用步骤:完成一次文件传输
完整操作流程如下:
- 通过
Tools --> SSH File Transfer打开传输面板。 - 填写Host、Port(默认 22)、User、Password四个连接信息。
- 选择Protocol(SCP 或 SFTP)。
- 填充Local File:点击Browse按钮,在本地文件系统中导航并选中要传输的文件;选中后文件完整路径会自动写入 Local File 输入框(
BtnBrowse_Click中通过OpenFileDialog实现)。 - 填充Remote File:手动键入远程主机上的目标文件系统路径,必须包含目标文件名,例如
/home/John/Documents/report.pdf(或以/结尾只填目录,工具会自动追加本地文件名)。 - 点击Transfer按钮,窗口底部的进度条会实时显示传输进度;传输完成或失败时,通知面板(Messages)会给出信息提示。
点击 Transfer 后,后台会依次执行以下校验与动作(见StartTransfer):
- 校验所有必填字段非空(Host / Port / User / Local File / Remote File),否则提示 "Please fill all fields.";
- 校验本地文件确实存在(
File.Exists),否则提示 "Local file does not exist."; - 校验端口是合法数字(
int.TryParse),否则提示 "Port must be a number."; - 创建
SecureTransferService并连接远程 SSH 服务; - 在后台线程(
IsBackground = true,STA 单元)中执行实际上传,期间禁用 Transfer 按钮防止重复点击,完成后恢复。
六、底层实现原理:SecureTransferService 与进度报告
文件传输的底层逻辑封装在 SecureTransferService.cs 中,它基于SSH.NET(Renci.SshNet)库实现(见 mRemoteNG.Plugins.SshTransfer.csproj 中的SSH.NET与Renci.SshNet.Async包引用)。
其工作流程分三步:
- Connect:按所选协议创建客户端并建立 SSH 连接——SCP 使用
ScpClient(host, port, user, password),SFTP 使用SftpClient(host, port, user, password),然后调用Connect()。 - Upload:
- SCP 走同步上传:
ScpClient.Upload(new FileInfo(SourceFile), DestinationFile); - SFTP 走异步上传:
SftpClient.BeginUploadFile(new FileStream(SourceFile, FileMode.Open), DestinationFile, AsyncCallback),返回SftpUploadAsyncResult,通过回调通知完成。
- SCP 走同步上传:
- Disconnect / Dispose:传输结束(无论成败)后断开连接并释放客户端资源。
进度条的实现也因协议而异,源码中的细节值得了解:
- SCP 模式:订阅
ScpClient.Uploading事件(ScpUploadEventArgs),从事件参数中读取文件总大小e.Size与已上传字节数e.Uploaded更新进度条。 - SFTP 模式:在主线程外的后台循环中轮询
AsyncResult.UploadedBytes,每 50ms 更新一次进度,直到AsyncResult.IsCompleted为真。针对大于 2GB(int.MaxValue)的文件,进度计算会自动切换到以 KB 为单位,避免整数溢出(fileInfo.Length > int.MaxValue ? /1024 : 原值)。
这些代码同时解释了文档中提到的"进度条显示传输进度":进度条的Maximum与Value由UpdateProgress设置,并通过Invoke保证跨线程更新 UI 的安全性。
七、故障排查(Troubleshooting)
当传输失败时,第一手排查依据是日志文件。SSH File Transfer 的详细运行日志(包括成功与失败的连接信息)记录在:
%AppData%\mRemoteNG\mRemoteNG.log该日志由 mRemoteNG 主程序的日志体系统一写入(参见 mRemoteNG/App/Logger.cs 与 log4net.config)。传输开始、完成、失败都会通过IPluginContext.Messages写入消息通知,失败详情(异常信息)会同时出现在通知面板与日志中。
常见问题与解决方法
1.ERROR - Please fill all fields(请填写所有字段)
- 原因:没有提供建立连接所需的全部信息。
- 解决:逐一确认 Host、Port、User、Local File、Remote File 均已填写(Password 允许为空,但会弹窗二次确认);检查 Remote File 是否包含文件名或以
/结尾的目录路径。
2.ERROR - SSH background transfer failed!(SSH 后台传输失败)
- 原因:很可能是权限问题——当前 SSH 账户对指定的远程路径没有写入权限。
- 解决:确认远程目标目录存在且当前用户对其有写权限;可以先用 SSH 登录远程主机,手动执行
touch /path/to/file验证权限,必要时改用sudo或更换可写目录;也可检查磁盘空间是否已满。
3.System.Net.Sockets.SocketException (0x80004005): No connection could be made because the target machine actively refused it(目标主机主动拒绝连接)
- 原因:本地主机无法在指定端口上联系到远程主机,即 TCP 层连接被拒绝。
- 解决:从以下方向排查:
- 防火墙规则:本地或远程防火墙是否放行了 SSH 端口(默认 22);
- SSH 服务状态:远程主机的 SSH 服务是否正在监听该端口(可用
ss -tlnp | grep 22或netstat -tlnp | grep sshd验证); - 端口与地址:确认 Port 配置与远程实际监听端口一致,Host 拼写正确且可解析(尝试
ping或Test-NetConnection -Port 22)。
八、进阶:该工具作为插件的构建与安装
由于 SSH File Transfer 在仓库中是一个独立插件工程(mRemoteNG.Plugins.SshTransfer),如果你希望从源码自行构建,可以按 README.plugins.md 的说明操作:
# 在仓库根目录构建全部插件 dotnet build mRemoteNG.Plugins.sln -c Release -p:Platform=x64构建产物中与本文相关的程序集为mRp.SshTransfer.dll(ARM64 构建时把x64替换为arm64)。安装时,需要把插件 DLL 复制到主程序的插件目录,同时把共享契约程序集mRp.Contracts.dll(来自mRemoteNG.PluginContracts工程)放到主程序的Assemblies目录:
Copy-Item .\mRemoteNG.PluginContracts\bin\x64\Release\net10.0-windows10.0.26100.0\mRp.Contracts.dll .\mRemoteNG\bin\x64\Release\Assemblies\ Copy-Item .\mRemoteNG.Plugins.SshTransfer\bin\x64\Release\net10.0-windows10.0.26100.0\mRp.SshTransfer.dll .\mRemoteNG\bin\x64\Release\Plugins\主程序默认从<应用输出目录>\Plugins加载插件;如果你在设置中配置了自定义插件目录,则会改用该目录。插件与主程序通过IPluginContext通信(消息通知、资源获取等),契约接口定义在 mRemoteNG.PluginContracts 中——这也是为什么该工具能无缝以标签页形式嵌入 mRemoteNG 主界面的原因。
结语
mRemoteNG 的 SSH File Transfer 工具将"SFTP/SCP 文件上传"这一高频运维需求直接内置到了远程连接管理器中:无需额外安装 WinSCP 等独立客户端,在同一个标签页界面里即可完成"从连接树带入凭据 → 选择本地文件 → 填入远程路径 → 一键传输"的完整链路。理解其前置条件、配置项含义、后台传输机制与日志定位方法,可以让你在遇到连接被拒、权限不足等常见故障时迅速定位根因,并在日常工作中稳定地完成安全的远程文件投递。
- 桌面应用
- 网络
【免费下载链接】mRemoteNG
mRemoteNG is the next generation of mRemote, open source, tabbed, multi-protocol, remote connections manager.
相关推荐
curl `--compressed-ssh` 详解:为 SCP/SFTP 传输启用 SSH 压缩以节省带宽
curl compressed ssh 详解:为 SCP/SFTP 传输启用 SSH 压缩以节省带宽 compressed ssh 是 curl 命令行在 SC
CLI网络通信curl/libcurl 使用 CURLOPT_SSH_PRIVATE_KEYFILE 配置 SSH 私钥进行 SFTP/SCP 认证
curl/libcurl 使用 CURLOPT_SSH_PRIVATE_KEYFILE 配置 SSH 私钥进行 SFTP/SCP 认证 本文基于 curl 官方
CLI网络通信AWS SFTP Transfer Family完整配置指南:5步搭建企业级文件传输服务
AWS SFTP Transfer Family完整配置指南:5步搭建企业级文件传输服务 想要快速搭建安全可靠的企业级文件传输服务吗?AWS SFTP Tran
示例工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考