|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Interrupted FtpWebRequest upload streamVS 2005 Team Dev. SP1
When an upload using ftpWebRequest fails because of a lost connection, I want to be able to use GetSize and then reposition the source file stream and try again where it left off using the "Append" this time. The problem is the crazy connection is left open to the FTP server even though KeepAlive is false, until about 4 minutes later when it times out. I verified that the connection is open with the FTP server. Until the connection is closed, the partial file doesn't show up on the destination server. How can you either force the connection to close or force the partial file to show up on the destination server? If I terminate the app instead of continuing on with the retry, the connection is closed. Thanks, Dean Hi Dean,
Have you tried to call FtpWebRequest.GetRequestStream().Close when the connection was lost? Sincerely, Walter Wang (waw***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. If you are using Outlook Express, please make sure you clear the check box "Tools/Options/Read: Get 300 headers at a time" to see your reply promptly. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Calling GetRequestStream().Close after a lost connection gives the following
error: Cannot re-call BeginGetRequestStream/BeginGetResponse while a previous call is still in progress. Here's my code: while (attempts < 5) try { // create ftpWebRequest object here byte[] fileContents; using (FileStream sourceStream = new FileStream("C:\myfile.exe", FileMode.Open, FileAccess.Read)) { int bytesRead; fileContents = new byte[sourceStream.Length]; do { bytesRead = sourceStream.Read(fileContents, 0, 4096); } while (bytesRead != 0); } using (Stream ftpStream = request.GetRequestStream()) { ftpStream.Write(fileContents, 0, fileContents.Length); ftpStream.Close(); // <----- causes the upload to take place } using (FtpWebResponse response = (FtpWebResponse) request.GetResponse()) { if ((int)response.StatusCode == 226 || (int)response.StatusCode == 227) { response.Close(); return true; // 226 and 227 means success } else errorMessage = response.StatusDescription; response.Close(); return false; } } catch (Exception e) { ++attempts; // I want to close or kill the old connection here. // What happens: when an exception occurrs because // of a lost connection, the current request gets in // a bad state and can't be controlled. It will die // after the destination server times it out. continue; // retry } } // end while Walter, I've tried the MaxIdleTime and ConnectionLeaseTimeout ServicePoint properties but they didn't help. If you don't know how to handle a hung request object, please help me get an answer from someone who does. I tried ignoring the old connection by just creating a new connection and then re-trying. If the new attempt succeeds, the file is successfully on the destination server. But because the old hung connection is still alive at the destination server, when it times out, the FTP server takes that partial (failed) file (doing a dir on the server shows the bad file is there and has a temporary name) and overwrites the new good complete file I just uploaded. Having that old hung request out there will keep you from correcting a failed upload until the hung connection is closed. - Dean Show quote "Walter Wang [MSFT]" wrote: > Hi Dean, > > Have you tried to call FtpWebRequest.GetRequestStream().Close when the > connection was lost? > > > Sincerely, > Walter Wang (waw***@online.microsoft.com, remove 'online.') > Microsoft Online Community Support > > ================================================== > Get notification to my posts through email? Please refer to > http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif > ications. If you are using Outlook Express, please make sure you clear the > check box "Tools/Options/Read: Get 300 headers at a time" to see your reply > promptly. > > Note: The MSDN Managed Newsgroup support offering is for non-urgent issues > where an initial response from the community or a Microsoft Support > Engineer within 1 business day is acceptable. Please note that each follow > up response may take approximately 2 business days as the support > professional working with you may need further investigation to reach the > most efficient resolution. The offering is not appropriate for situations > that require urgent, real-time or phone-based interactions or complex > project analysis and dump analysis issues. Issues of this nature are best > handled working with a dedicated Microsoft Support Engineer by contacting > Microsoft Customer Support Services (CSS) at > http://msdn.microsoft.com/subscriptions/support/default.aspx. > ================================================== > > This posting is provided "AS IS" with no warranties, and confers no rights. > > Hi Dean,
I have done some test on my side and I think the server is really responsible to release the connection, there's really not much we can do from the client side. Here's my test configuration/steps: 1) I downloaded a ftp server Serv-U from http://www.serv-u.com and installed on system B, to ease test, I enabled anonymous user to read/write files on the ftp server 2) On my system A, I created following test program: ============ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net; using System.Threading; namespace ConsoleApplication3 { class Program { static void Main(string[] args) { UploadFile(@"f:\test.exe", "ftp://serverB/test.exe", 5000); Console.WriteLine("Press ENTER"); Console.ReadLine(); } static bool IsFtpFileExists(string remoteUri, out long remFileSize) { FtpWebRequest request = (FtpWebRequest)WebRequest.Create(remoteUri); FtpWebResponse response; request.Method = WebRequestMethods.Ftp.GetFileSize; try { response = (FtpWebResponse)request.GetResponse(); remFileSize = response.ContentLength; return true; } catch (WebException we) { response = we.Response as FtpWebResponse; if (response != null && response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable) { remFileSize = 0; return false; } throw; } } static void UploadFile(string localFile, string remoteUri, int attempts) { FileInfo fi = new FileInfo(localFile); long remFileSize = 0; FtpWebRequest request = null; while (--attempts >= 0) { try { request = (FtpWebRequest)WebRequest.Create(new Uri(remoteUri)); request.Timeout = 3000; if (IsFtpFileExists(remoteUri, out remFileSize)) { Console.WriteLine("File already exists, RESUME"); request.Method = WebRequestMethods.Ftp.AppendFile; } else { Console.WriteLine("File not already exists, UPLOAD"); request.Method = WebRequestMethods.Ftp.UploadFile; } request.ContentLength = fi.Length - remFileSize; request.UsePassive = false; using (Stream requestStream = request.GetRequestStream()) { using (FileStream fs = File.Open(localFile, FileMode.Open)) { fs.Seek(remFileSize, SeekOrigin.Begin); const int BUFFER_SIZE = 8192; byte[] buffer = new byte[BUFFER_SIZE]; int readBytes = 0; do { readBytes = fs.Read(buffer, 0, BUFFER_SIZE); requestStream.Write(buffer, 0, readBytes); System.Threading.Thread.Sleep(500); } while (readBytes != 0); } } Console.WriteLine("Done"); using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) { Console.WriteLine(response.StatusCode); } break; } catch (WebException we) { Console.WriteLine(we.Message); Thread.Sleep(500); } } } } } ============ 3) Run this test program, it will start upload file f:\test.exe to the ftp server; while it's transfering, disable the network connection "Local Area Connection" to simulate a connection broken error; and re-enable it again after some time. From the ftp server, serv-u administrator shows there's a connection keeps open. 4) Terminate the test program, the connection still opens on the server. 5) Now use another ftp client to test this behavior, you will find the connection is also kept open on the ftp server. Also, in this case, serv-U actually don't use temporary file, therefore you can see the target file exists but while the orphan connection keeps open, you cannot delete or overwrite file -- it's locked by the thread receiving the file on the ftp server. Since using a commercial ftp client also shows behavior, I think we really cannot do much from client-side. It's totally controlled by the ftp server, the server decides when to times out and dropps the orphan connection. Regards, Walter Wang (waw***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi Dean,
In my last reply to your post, I described my research result and it seems the orphan connection to the ftp server is really up to the server to close it in some circumstances. After the connection is the broken, the previous FtpWebRequest and its related stream objects are in an inconsistent state and will not be able to recover correctly. At this stage, only the server could decide when to drop the broken connection. Please feel free to let me know if you have any concerns or anything unclear, thanks. Best regards, Walter Wang MSDN Managed Newsgroup Support |
|||||||||||||||||||||||