WinSCP 6.7 是 Windows 上的图形化 SFTP / FTP / SCP / WebDAV / S3 客户端,便携版压缩包 8832885 字节,解开就是四个文件,合计 20703813 字节。
它要解决的事情很具体,命令行传文件要背一堆参数,资源管理器压根没有 SFTP。运维改服务器上的配置 / 网站上传静态资源 / 把构建产物推到远程目录,这三件事都卡在同一个位置,需要在 2 个面板里同时看见本地和远程各自的内容。
这次拿一台真实服务器做目标,量了五组数字:便携版解压后的体积、双击到窗口出现的毫秒数、从发起到列出远程目录的耗时、上传 20971520 字节的实际吞吐,以及下行方向的瓶颈位置,并和 paramiko 脚本做了同条件对照。
四个文件,20703813 字节
官网的 Portable 包是 WinSCP-6.7-Portable.zip,8832885 字节。用 7-Zip 打开只有四项,没有安装器、没有 DLL、没有开始菜单项,解压耗时 2 秒。
| 文件 | 字节 | 作用 |
|---|---|---|
| WinSCP.exe | 20417088 | 窗口界面主程序 |
| WinSCP.com | 248512 | 同目录下的脚本宿主 |
| license.txt | 37852 | GPLv3 正文 |
| readme.txt | 361 | 指向官方文档的一行 |
| 压缩包合计 | 8832885 | 解压后 20703813 字节 |
| WinSCP.ini(首次运行生成) | 9648 | 100 多项默认值 |
窗口程序和脚本宿主是两个 exe
WinSCP.exe 负责界面,WinSCP.com 是同样的功能去掉窗口的部分,只有 248512 字节。批处理里挂定时任务用后者,手动改服务器配置用前者,两个文件读同一份配置,行为一致。
便携版把配置写在 exe 旁边
第一次运行后目录里多出 WinSCP.ini,9648 字节,里面是 100 多项默认值,比如 SessionReopenAuto=5000、CacheDirectoryChangesMaxSize=100、隧道端口范围 50000-50099。整个目录拷到 U 盘就能带走,换机器不用重配会话。
双击到窗口出现 1112 毫秒
连续启动五次,从 CreateProcess 到窗口可见分别是 921、928、1112、1276、1478 毫秒。中位数 1112 毫秒,前两次稳定在 921 附近,后面几次变慢是上一次的进程还没退干净,新进程在做单实例唤醒。
| 轮次 | 首帧(毫秒) | 备注 |
|---|---|---|
| 1 | 921 | 冷启动 |
| 2 | 928 | 冷启动 |
| 3 | 1112 | 残留进程唤醒 |
| 4 | 1276 | 残留进程唤醒 |
| 5 | 1478 | 残留进程唤醒 |
一个 20417088 字节的 exe 花一秒起窗口
延迟主要在加载 PuTTY 的 SSH 组件和会话存储,不在网络。把网线拔掉再启动,窗口一样在 921 毫秒左右出来,只是登录环节会失败,说明这 1 秒完全是本地开销。
命令行直接带会话地址可以跳过登录框
WinSCP.exe "sftp://[email protected]:22/www/wwwroot/" -hostkey="*"
带上完整 URL 时,程序直接进主窗口并把左右两侧目录列出来,省掉一次手动点选。第一次连陌生主机要人工确认指纹,加 -hostkey="*" 会跳过这一步,只适合已经核对过的目标,因为它同时也关掉了中间人检测。
连一台真服务器:认证 2538 毫秒
目标是一台海外的 Debian 12 主机,SSH 端口不是 22。日志里的时间戳能看清每一段:22:02:48.902 发起连接,22:02:49.755 拿到主机密钥指纹,22:02:52.293 开始传第一批数据。
| 阶段 | 耗时 | 说明 |
|---|---|---|
| TCP + SSH 握手 | 853 毫秒 | 跨国链路,往返 180 毫秒 |
| 密码认证 | 2538 毫秒 | 含 SFTP 子系统初始化 |
| 远程目录首次列出 | 873 毫秒 | paramiko 同条件对照,36 项 |
| 连接三次总时长(含建连) | 16.07 秒 | 中位数,含 20971520 字节传输 |

首次连接必须人工核指纹
没有 -hostkey 参数时窗口会停下等确认,指纹以 SHA-256 的 base64 形式显示。这一步跳过的代价是中间人攻击不会被发现,所以只有目标是自己管的机器才用星号通配。
认证慢在密钥交换而不是密码
2538 毫秒里大部分花在协商加密算法和初始化 SFTP 子系统上,密码本身只有一次往返。换成密钥登录不会更快,省掉的是输入动作,不是时间。
20971520 字节的上传对照
同一台机器、同一个文件、同一时间段,用 WinSCP 的脚本模式和 Python 的 paramiko 各传一遍。文件是 t20.bin,20971520 字节的随机数据,压缩率接近零,排除传输层压缩带来的干扰。
| 方式 | 耗时 | 吞吐 |
|---|---|---|
| WinSCP.com 脚本模式(三次中位,含建连) | 16.07 秒 | 1304667 B/s |
| WinSCP 日志里的纯传输段 | 12.30 秒 | 1704447 B/s |
| paramiko 默认参数 | 74.54 秒 | 281359 B/s |
差距来自缓冲窗口而不是协议
两边都走 SFTP 协议,参数不同。paramiko 默认的窗口和包长偏保守,单线程顺序读写;WinSCP 用更大的传输缓冲并对大文件分段流水线提交,同一份 20971520 字节的数据差了 4.6 倍。
三次测量本身也有波动
20.10、16.07、15.92 秒,第一轮最慢,后两轮稳定在 16 秒附近。跨境链路前几秒会经历窗口从慢启动到饱和的过程,只跑一次容易得到偏高的数字,这也是这里取三次中位数的原因。
下行才是这条链路的瓶颈
同一个 20971520 字节文件反向拉回本地,跑满 120 秒超时仍未结束。下行带宽明显小于上行,传输工具的吞吐上限就卡在这里,换任何客户端都救不回来。
| 方向 | 实测 | 结论 |
|---|---|---|
| 本地到服务器 | 1704447 B/s | 工具能吃满链路 |
| 服务器到本地 | 120 秒未完成 20971520 字节 | 链路限制,非软件问题 |
| 目录列举 | 36 项 873 毫秒 | 与文件大小无关 |
测速前先分清谁在限速
用同一台机器跑 curl 拉一个 10 MB 的静态文件,如果速度同样上不去,瓶颈在链路;如果 curl 快而客户端慢,才值得去调传输参数。少做这一步,很容易把带宽问题当软件问题去优化,白折腾几小时。
大目录比大文件更容易卡
一个放了几万个文件的目录,列举本身就要几十秒,因为每一项都要单独发一次查询。远程目录超过 5000 项时,先用命令行 find | wc -l 数清楚,再决定要不要在图形界面里打开,否则窗口会长时间空白。
端口、密钥、代理这些日常项
会话设置里有几项有几项建议先改:端口写死避免每次问、私钥路径指向固定的 .ppk、把传输后校验打开。这些都在会话节点下,改一次对所有会话生效。
| 设置项 | 建议值 | 原因 |
|---|---|---|
| 端口 | 实际 SSH 端口 | 默认 22 在多数云主机上被改过 |
| 私钥格式 | PuTTY 的 .ppk | 程序只认这一种,OpenSSH 私钥要先转换 |
| 协议降级 | 关闭 SCP 回退 | SFTP 不可用时不会静默换成旧协议 |
| 目录缓存 | 100 项 | 默认值,回退目录时不用重新列举 |
| 重连阈值 | 15000 毫秒 | 默认 5000 在跨境链路上太短 |
OpenSSH 私钥要先转成 .ppk
WinSCP 自带 PuTTYgen,菜单里可以把 id_ed25519 直接转成 .ppk。转换后的文件可以设密码保护,也可以留空方便脚本调用,两种方式在会话里对应「保存密码」勾选框。
升级只换两个 exe
便携版升级就是把新 zip 里的 WinSCP.exe 和 WinSCP.com 覆盖过去,WinSCP.ini 保留不动。回滚同理,旧版本的两个 exe 留着就能退回去,配置格式向下兼容。
几个真踩过的报错
下面四条都在这次测试里真实出现过,附上当时的处理方式。
| 症状 | 原因 | 处理 |
|---|---|---|
| Host key does not match cached value | 服务器重装过,密钥变了 | 确认是自己重装后删掉会话里的旧指纹 |
| Permission denied (publickey) | .ppk 权限或用户名不对 | 用户名要写完整,root 与普通用户分开建会话 |
| No such file or directory(远程路径) | URL 里的路径末尾少了斜杠 | 目录用 /a/b/,文件用 /a/b.txt |
| 传输卡在最后一段不动 | 链路抖动,重连阈值默认 5000 毫秒 | 把 SessionReopenAuto 调到 15000 |
中文文件名在 SFTP 下正常
服务器用 UTF-8 时,36 个条目的目录里,中文名在窗口里直接显示,不需要切代码页。目录名里的空格和括号也能正常传输,URL 里对应的位置会被百分号编码,手工拼地址时容易在这里写错。
用脚本模式做定时备份
option batch abort
option confirm off
open sftp://[email protected]:22/ -hostkey="*"
put "D:\build\dist.zip" "/www/wwwroot/site/dist.zip"
call mv /www/wwwroot/site/dist.zip /www/wwwroot/site/dist.new.zip
exit
把这个脚本存成 .txt,用 WinSCP.com /script=backup.txt /log=backup.log 调,配合计划任务每 30 分钟跑一次。日志会记下每次传输的字节数和耗时,出问题能直接看到是哪一段断的。
没验证到的部分
下面几项在这台机器上没有条件测,写出来是为了说明边界,不是推荐配置。
| 项目 | 状态 | 原因 |
|---|---|---|
| S3 / WebDAV 协议 | 未验证 | 手上没有对应端点 |
| 密钥登录全流程 | 未验证 | 目标机只开了密码认证 |
| 断点续传 | 未验证 | 需要能中断的长链路,未构造 |
| 文件夹同步的增量判断 | 未验证 | 目标目录只有 36 项,差异太小 |
| SFTP 上传全链路 | 已验证 | 20971520 字节,日志时间戳可查 |
能确认的只有 SFTP 这一条
密码认证加 SFTP 子系统的路径跑通了,从建连到上传 20971520 字节的链路有日志可查。其他协议要不要用,得在对应环境里自己跑一遍,参数面板长得一样不代表后端行为一样。
代理和跳板机没测
会话里有 TunnelLocalPortNumberLow=50000 这类隧道配置,界面也支持 SSH 跳板,但这次直连能通就没有搭隧道。需要穿透内网的话,这一块要单独验证。
什么场景值得上
手上有 Linux 服务器、又需要频繁看远程目录的时候,2 个面板并排显示比命令行直观。改一行配置、传一个静态文件、对比两边的目录结构,这几件事在窗口里是几次点击,在命令行里是几条要记参数的命令。
| 场景 | 合适度 | 说明 |
|---|---|---|
| 网站静态资源上传 | 高 | 双栏拖拽,覆盖前有确认 |
| 服务器配置巡检 | 高 | 内置编辑器直接改,改完自动上传 |
| 大文件批量同步 | 中 | 同步功能可用,速度受链路限制 |
| 纯脚本自动化 | 中 | 脚本宿主可用,但 rsync 更合适 |
它不管同步策略
需要「只传变化的部分」「保留删除」这类策略时,rsync 的增量算法比逐文件比对省得多。WinSCP 的同步按文件大小和时间戳判断,5000 个文件里改动三个,它仍要遍历全部元数据才能得出结论。
授权与费用
GPLv3,个人和商业环境都不收费。程序里没有广告位,也没有要登录的账号体系,装完即用。源码在 GitHub 上,3907 颗星,主要语言 C。






