FluentFTP传输不同文件时连接中断异常表现不一致求助
问题描述
使用FluentFTP向内部FTP服务器传输文件时,出现异常表现不一致的问题:当FTP连接中断时,传输*.7z文件会触发异常,服务恢复后还能重新连接;但传输*.opus文件时,程序会卡在await状态无响应。
报错信息:
上传文件到服务器时出错。查看InnerException获取更多信息。(原英文:
Error while uploading the file to the server. See InnerException for more info.)
相关代码如下:
public class FileWatcher { public static async Task Main(string[] args) { do { Console.WriteLine("Und los geht es!"); await UploadFileAsync(); await Task.Delay(15000); } while (true); } static async Task UploadFileAsync() { try { string[] filePath = Directory.GetFiles(@"C:\temp\ftpupload", "*", SearchOption.AllDirectories); var token = new CancellationToken(); using (AsyncFtpClient client = new AsyncFtpClient()) { client.Host = "192.168.1.100"; client.Port = 21; client.Credentials.UserName = "test"; client.Credentials.Password = "test123"; client.Config.EncryptionMode = FtpEncryptionMode.None; client.Config.InternetProtocolVersions = FtpIpVersion.IPv4; client.Config.ValidateAnyCertificate = true; client.Config.ConnectTimeout = 10000; Console.WriteLine("Connecting......"); await client.AutoConnect(token); Console.WriteLine("Connected!"); foreach (var erg in filePath) { Console.WriteLine("File is uploading: " + erg.GetFtpFileName()); await client.UploadFile(erg, "/" + erg.GetFtpFileName(), FtpRemoteExists.Overwrite, true, token: token); Console.WriteLine("File successfully uploaded: " + erg.GetFtpFileName()); System.IO.File.Delete(erg); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } } }
问题分析与解决建议
核心原因
- 无效的取消令牌:你创建的
CancellationToken是空实例,没有任何超时或取消逻辑,当连接中断后,FluentFTP无法触发取消操作,导致程序卡在await状态。 - 文件传输特性差异:.7z文件通常体积大,传输时数据包交互频繁,连接中断后更容易触发底层网络异常;而.opus文件体积小或传输间隔长,网络中断后无法及时触发超时检测。
解决步骤
添加带超时的取消令牌
替换空的CancellationToken为带超时的CancellationTokenSource,确保连接中断后能自动取消操作,避免卡死:// 替换原var token = new CancellationToken(); using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(5)); // 设置5分钟超时,可按需调整 var token = cts.Token;配置FluentFTP的传输超时参数
除了已设置的ConnectTimeout,添加读取、发送和数据连接的超时配置,增强异常检测能力:client.Config.ReadTimeout = 30000; // 30秒读取超时 client.Config.SendTimeout = 30000; // 30秒发送超时 client.Config.DataConnectionConnectTimeout = 10000; // 10秒数据连接超时细化异常捕获与日志
捕获FluentFTP的特定异常,并输出内部异常信息,便于精准排查问题:catch (FtpConnectionException ex) { Console.WriteLine($"连接异常:{ex.Message}"); if (ex.InnerException != null) Console.WriteLine($"内部异常:{ex.InnerException.Message}"); } catch (FtpCommandException ex) { Console.WriteLine($"FTP命令异常:{ex.Message}"); if (ex.InnerException != null) Console.WriteLine($"内部异常:{ex.InnerException.Message}"); } catch (Exception ex) { Console.WriteLine($"未知异常:{ex.Message}"); if (ex.InnerException != null) Console.WriteLine($"内部异常:{ex.InnerException.Message}"); }优化文件上传循环
为单个文件上传添加独立的异常处理和取消检查,避免单个文件上传失败导致整个循环停滞:foreach (var erg in filePath) { if (token.IsCancellationRequested) break; try { Console.WriteLine("File is uploading: " + erg.GetFtpFileName()); await client.UploadFile(erg, "/" + erg.GetFtpFileName(), FtpRemoteExists.Overwrite, true, token: token); Console.WriteLine("File successfully uploaded: " + erg.GetFtpFileName()); System.IO.File.Delete(erg); } catch (Exception ex) { Console.WriteLine($"上传文件{erg.GetFtpFileName()}失败:{ex.Message}"); // 可根据需求添加重试逻辑 } }
内容的提问来源于stack exchange,提问作者newby567
相关产品推荐
相关产品推荐

