C# FTP下载约1GB大文件时出现挂起问题求助
Hey there, I get it—frustrating when small files download smoothly but 1GB+ transfers hang, especially after trying all the usual fixes you found online. Let's break down what might be going on with your code and how to fix it.
Key Issues in Your Current Code
Looking at your snippet, a few settings stand out as potential culprits for large file hangs:
- Active vs Passive FTP: You’ve set
UsePassive = false, which uses active mode. Many modern firewalls, routers, or cloud environments block active FTP’s reverse connection from the server to your client—this often doesn’t show up with small files (since transfers finish quickly) but kills long-running large file transfers. - Unnecessary
Abort()Call: CallingftpRequest.Abort()after the transfer completes can interrupt clean connection shutdown and leave resources hanging. - Overly High Connection Limit: Setting
ServicePoint.ConnectionLimit = 1000is way more than needed for a single transfer, and might cause unexpected resource allocation issues.
Recommended Fixes
Try adjusting these settings and simplifying the flow:
Switch to Passive Mode (critical for most network environments):
SetftpRequest.UsePassive = true—this lets your client initiate both control and data connections, avoiding firewall blocks on incoming server connections.Remove the
Abort()Call:
Theusingstatements already handle disposing the response and streams cleanly. Aborting the request post-transfer can cause unexpected connection issues.Tweak
KeepAlivefor Long Transfers:
SetftpRequest.KeepAlive = falseto ensure the connection closes properly once the download finishes. If you need persistent connections, verify your FTP server’s keep-alive timeout is longer than your maximum expected transfer time.Reduce Connection Limit:
LowerServicePoint.ConnectionLimitto a reasonable number like 10—you only need one connection for this single download.
Modified Code Example
System.Net.ServicePointManager.Expect100Continue = false; System.Diagnostics.Trace.WriteLine($"FTP: Download {this._URL}{fixURL(this._Folder).Replace("\\", "/")}{fixURL(ftpFileName)}"); FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create( $"{this._URL}{fixURL(this._Folder).Replace("\\", "/")}{fixURL(ftpFileName)}"); ftpRequest.Credentials = new NetworkCredential(this._UserName, this._Password); ftpRequest.UsePassive = true; // Switch to passive mode ftpRequest.KeepAlive = false; // Close connection after transfer ftpRequest.UseBinary = true; ftpRequest.Timeout = -1; ftpRequest.ReadWriteTimeout = 1000 * 60 * 60 * 5; ftpRequest.ServicePoint.ConnectionLimit = 10; // Reasonable connection limit ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile; using (FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse()) using (Stream ftpStream = ftpResponse.GetResponseStream()) using (FileStream fileStream = File.Create(Path.Combine(outFolder, ftpFileName))) { ftpStream.ReadTimeout = 1000 * 60 * 60 * 5; byte[] buffer = new byte[8192]; // Standard efficient buffer size int bytesRead; long bytesSoFar = 0; while ((bytesRead = ftpStream.Read(buffer, 0, buffer.Length)) > 0) { fileStream.Write(buffer, 0, bytesRead); bytesSoFar += bytesRead; System.Diagnostics.Trace.WriteLine($"FTP: Download Read Block {bytesSoFar:N0}"); } System.Diagnostics.Trace.WriteLine($"FTP: Download completed successfully. Total bytes: {bytesSoFar:N0}"); }
Additional Checks
- Verify your FTP server’s configuration: Ensure there’s no maximum file size limit, and that server-side timeouts are set to accommodate 1GB transfers.
- Check network stability: Large transfers are more sensitive to packet loss—run a ping test to the server during a hang to see if there’s intermittent connectivity.
I’ve dealt with similar issues before, and switching to passive mode usually resolves the large-file hang problem in most network setups. Give these changes a shot and let us know how it goes!
内容的提问来源于stack exchange,提问作者Brian Kitt

