C# SFTP文件上传 C#如何使用SSH.NET或FluentFTP进行安全文件传输

来源:这里教程网 时间:2026-02-21 17:41:49 作者:

SSH.NET上传SFTP文件时连接被拒绝或超时

多数情况不是代码写错,而是服务端SSH配置没开SFTP子系统或防火墙拦了22端口。先用

ssh -v user@host
在终端确认基础SSH连得通;若能连但
SftpClient
SocketException
TimeoutException
,重点检查
Renci.SshNet.ConnectionInfo
Port
是否显式设为22(默认是22,但某些私有SFTP服务跑在非标端口)。

常见疏漏点:

ConnectionInfo
构造时没传
PrivateKeyFile
PasswordConnectionInfo
,却调用了
new SftpClient(conn)
——会静默 fallback 到无认证模式,直接被拒
使用私钥时没调用
privateKey.Load(<code>passphrase
)(如有口令),导致
AuthenticationException
服务器启用了
ForceCommand internal-sftp
但禁用了
chroot
外的路径访问,
UploadFile
指定的远程路径必须是绝对路径且在受限目录内

FluentFTP上传大文件时内存暴涨或卡死

FluentFTP
默认用
FileStream
读取本地文件再分块上传,对>100MB的文件容易触发GC压力或
OutOfMemoryException
。关键要改用流式上传而非全量加载:

正确做法是传

Stream
而非
string
路径:

using var fileStream = File.OpenRead(@"C:\large.zip");
await client.UploadAsync(fileStream, "/remote/large.zip");

注意:

别用
UploadAsync(string, string)
重载——它内部会
File.ReadAllBytes
确保
FtpClient
已设置
client.DataConnectionType = FtpDataConnectionType.AutoActive
(尤其内网穿透场景)
若目标路径含中文,需确认服务器FTP服务支持UTF-8(
client.Encoding = System.Text.Encoding.UTF8

SSH.NET与FluentFTP选型:SFTP还是FTP over TLS?

名字都带“FTP”,但协议层完全不同:

SSH.NET
走SFTP(SSH File Transfer Protocol,基于SSH通道),
FluentFTP
主攻FTP/FTPS(FTP over TLS)。选错等于协议不匹配,必然失败。

判断依据看服务端暴露的端口和认证方式:

端口是22、认证用SSH密钥或Linux系统账号 → 必须用
SSH.NET
端口是21/990、要求TLS证书、用户名密码明文传输(但信道加密)→ 用
FluentFTP
FtpEncryptionMode.Explicit
端口是22但服务端实际跑的是Dropbear等轻量SSH,可能不支持SFTP子系统 → 用
SSH.NET
SshClient
先执行
RunCommand("sftp -V")
验证

上传后校验文件完整性不能只比对大小

网络中断或缓冲区问题可能导致上传截断,但

Length
碰巧一致。生产环境必须加哈希校验:

SSH.NET方案:上传后立刻用

SftpClient
执行
ReadAllText("sha256sum /remote/file")
(需服务端装
coreutils
);或更稳妥地,上传前本地算
SHA256.Create().ComputeHash(stream)
,上传后再用
SftpClient
下载远程文件小片段+追加计算(避免全量下载)。

FluentFTP方案:用

client.GetChecksum("SHA256", "/remote/file")
(仅限支持
MD5
/
SHA256
扩展的FTP服务器,如ProFTPD + mod_digest)。

最易被忽略的一点:SFTP服务器若禁用

exec
通道(如
ForceCommand internal-sftp
),就无法运行
sha256sum
,此时只能靠客户端本地重新下载并完整比对哈希——这意味着你得预留双倍存储和带宽。

相关推荐