FtpWebRequest request stream not closing

  • Thread starter Thread starter kh
  • Start date Start date
K

kh

Hi. I have an issue with file uploads using the FtpWebRequest class. When the
code is deployed at a client site transfer speed is very slow. I write the
local file stream to the request stream but with large files (i.e. long
upload times) my app hangs on the call to requestStream.Close():

// sourceStream is a FileStream to a local file
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(_uri);
....
Stream requestStream = request.GetRequestStream();
byte[] buffer = new byte[DEFAULT_BUFFER_LENGTH];
int bytesRead;
do
{
bytesRead = sourceStream.Read(buffer, 0, buffer.Length);
requestStream.Write(buffer, 0, bytesRead);
} while (bytesRead >= buffer.Length);

// code hangs here
requestStream.Close();

FtpWebResponse response = (FtpWebResponse) request.GetResponse();
response.Close();

The corresponding server log is as follows:

USER MyUsername - 331 0 0 0 0 FTP - - - -
PASS - - 230 0 0 0 0 FTP - - - -
CWD /Incoming - 250 0 0 0 0 FTP - - - -
created /Incoming/MyFile.xml.pgp - 226 0 0 53031735 457167 FTP - - - -

Note the 226 return code (i.e. success).

If the user uploads small files all works as expected. I know there can be
issues with idle command chanels timing out, but what can I do to correct
this, or at least recover from it? At the moment I cannot even throw an
exception.

Cheers
 
I forgot to mention that the file is successfully uploaded even though the
app hangs at the call the requestStream.Close()
 
OK, ReadWriteTimeout allows me to catch an exception here. If I set it to a
lower value (e.g. one minute) the stream closes but a call to GetResponse
causes a WebException to be thrown with FtpStatusCode.ConnectionClosed. I
presume I can ignore this if the source stream is full written to the request
stream.

Would be nice if there was a way to keep the command channel active during
large file transfers. How do commercial FTP products do this? I see there is
a NOOP command which could be periodically sent to the server. Or am I
missing something.

kh
 
Peter

I am being a good citizen and closing the stream before "sending" the
request as per the documentation. To send the request you get the
corresponding FtpWebResponse. To complete the request you then close the
FtpWebResponse.

No, FtpWebRequest is designed for stateless FTP interaction and can only
send one command per request (although this is not strictly true, for example
renaming a file involves sending RNFR and RNTO commands). I just wondered if
the MS team responsible for these classes has considered a mechanism to
"tickle" the command channel so that it does not remain idle during large
file transfers.

A workaround would be to upload the file in chunks (using the append command
for each chunk) so that the command channel remains active.

kh
 
Back
Top