Connection Closed; Transfer Aborted

Oct 21, 2013 at 8:19 PM

I'm getting the following exception from the CloseDataStream method occasionally (usually on bigger files).

System.Net.FtpClient.FtpCommandException occurred
Message=Connection closed; transfer aborted.
   at System.Net.FtpClient.FtpClient.CloseDataStream(FtpDataStream stream) in d:\Dropbox\Projects\mWiki3\mWiki3\System.Net.FtpClient\FtpClient.cs:line 1287

The odd thing is, this only happens in Release mode. If I run in debug mode (and can see all your trace writing to the debug console), it works. If I comment out your Debug.Write(message) line in FtpTrace I can recreate the problem. If I replace the Debug.Write(message) for a System.Threading.Sleep(25) the problem goes away. It's as though the delay this Debug.Write causes gives the stream enough time to catch up.

Any ideas?

Oct 21, 2013 at 8:25 PM
Edited Oct 22, 2013 at 9:26 AM
Interestingly, if I change the Read method on your FtpSocketStream to the below the problem goes away:
    public override int Read(byte[] buffer, int offset, int count) {
        if (BaseStream == null)
            return 0;

        m_lastActivity = DateTime.Now;

        return BaseStream.Read(buffer, offset, count);
Oct 22, 2013 at 9:41 AM
I have also noticed that removing the async stuff from the Read method has greatly improved performance.
Oct 22, 2013 at 1:40 PM
I’ll try to look into some of these issues today. FYI, if I stop using the async methods then the ability specify a timeout is lost. That’s the reasons they’re being used. I’ll dig around and see if any of these are known issues with the async socket and stream methods since they’re part of the framework.

Oct 22, 2013 at 1:45 PM
I suspect it's because of the tiny 1 byte buffer. Async is traditionally used for things that are going to take more time than you're willing to accept as part of a linear routine, and the async will add a load of bloat to something that's taking a minuscule amount of time, which would explain why I'm seeing performance improvements. Would probably work better with a bigger buffer - but then would need a way of working out the EOL etc.
Oct 22, 2013 at 2:01 PM
What is the server software you're connecting to?
Oct 22, 2013 at 2:01 PM
Microsoft IIS6 FTP
Oct 22, 2013 at 2:02 PM
Also, is this an upload or a download the exception is occurring on? It sounds like an upload based on the server's response (the transfer aborted error).
Oct 22, 2013 at 2:03 PM
Oct 22, 2013 at 2:13 PM
I think I remember a similar issue well over a year ago where I had to implement a "kludge" to keep the control connection alive on IIS because it would timeout during long transfers. It's completely un-related to the asynchronous calls. Just for the sake of testing, check this out (and try increasing the connection timeout in IIS) and see if the problem goes away:
Oct 22, 2013 at 2:13 PM
The work around was in an older version of System.Net.FtpClient, in the _1 branch. It doesn't exist in the current branch in case you were wondering.
Oct 22, 2013 at 2:16 PM

It’s not long transfers it’s affecting – some of these files were only 20kb – however they were always bigger than the majority – about 1-2kb. It works without the async 100% of the time, so I suspect it’s the async. I’ve changed the code for my project anyway – was just letting you know. If I get some time I’ll write some alternative timeout code.