0 votes
by (120 points)
edited

I'm getting an error when I use the PutFile method to upload a file via FTP. The error I get is "The server has closed the connection" however upon further inspection it looks like the file has been uploaded just fine. All bytes are there. This doesn't happen to all FTP server, just a specific one is causeing this problem.

Is there a setting that I could change that could prevent this "false" error?

by (147k points)
Please send us a communication log produced using the Ftp object's LogWriter property, as described at http://www.rebex.net/kb/logging.aspx - this should make it possible to tell more!
by (120 points)
2010-05-06 11:46:05.602 INFO Ftp(1) Command: STOR Test.jpg 2010-05-06 11:46:05.799 INFO Ftp(1) Response: 150 Opening data connection for Test.jpg 2010-05-06 11:46:05.802 DEBUG Ftp(1) Info: Data connection accepted from 217.110.76.88:20. 2010-05-06 11:46:08.847 DEBUG Ftp(1) Info: Closing uploading data connection. 2010-05-06 11:46:08.848 DEBUG Ftp(1) Info: Waiting for data transfer ending message. 2010-05-06 11:46:08.945 DEBUG Ftp(1) Info: Control connection closed.
by (120 points)
2010-05-06 11:46:08.951 ERROR Ftp(1) Info: Error while closing data connection: Rebex.Net.FtpException: The server has closed the connection. at wWGvS.AgXIfM.BMJzdYZ(Byte[] , Int32 ) at wWGvS.AgXIfM.BbLKfs(String& ) at wWGvS.AgXIfM.KsZclZ() at Rebex.Net.Ftp.cgrDQE(Int32 ) at Rebex.Net.Ftp.AwjivcZ(AoLBks , FtpResponse , String , Int64 , String , Boolean ) at wWGvS.AayBuI.Close()
by (120 points)
This might be helpful also starting right after I logged in: 2010-05-06 11:45:57.441 INFO Ftp(1) Command: FEAT 2010-05-06 11:45:57.536 INFO Ftp(1) Response: 211-Extensions supported: 2010-05-06 11:45:57.536 INFO Ftp(1) Response: AUTH TLS 2010-05-06 11:45:57.536 INFO Ftp(1) Response: CCC 2010-05-06 11:45:57.536 INFO Ftp(1) Response: CLNT 2010-05-06 11:45:57.536 INFO Ftp(1) Response: CPSV 2010-05-06 11:45:57.536 INFO Ftp(1) Response: EPRT 2010-05-06 11:45:57.536 INFO Ftp(1) Response: EPSV 2010-05-06 11:45:57.536 INFO Ftp(1) Response: MDTM
by (120 points)
2010-05-06 11:45:57.536 INFO Ftp(1) Response: MFCT 2010-05-06 11:45:57.536 INFO Ftp(1) Response: MFMT 2010-05-06 11:45:57.536 INFO Ftp(1) Response: MLST type*;size*;create;modify*; 2010-05-06 11:45:57.536 INFO Ftp(1) Response: MODE Z 2010-05-06 11:45:57.536 INFO Ftp(1) Response: PASV 2010-05-06 11:45:57.536 INFO Ftp(1) Response: PBSZ 2010-05-06 11:45:57.536 INFO Ftp(1) Response: PROT 2010-05-06 11:45:57.536 INFO Ftp(1) Response: REST STREAM 2010-05-06 11:45:57.536 INFO Ftp(1) Response: SIZE 2010-05-06 11:45:57.536 INFO Ftp(1) Response: SSCN
by (120 points)
2010-05-06 11:45:57.536 INFO Ftp(1) Response: TVFS 2010-05-06 11:45:57.536 INFO Ftp(1) Response: UTF8 2010-05-06 11:45:57.536 INFO Ftp(1) Response: XCRC "filename" SP EP 2010-05-06 11:45:57.536 INFO Ftp(1) Response: XMD5 "filename" SP EP 2010-05-06 11:45:57.537 INFO Ftp(1) Response: XSHA1 "filename" SP EP 2010-05-06 11:45:57.537 INFO Ftp(1) Response: 211 End. 2010-05-06 11:45:57.538 INFO Ftp(1) Command: SYST 2010-05-06 11:45:57.634 INFO Ftp(1) Response: 215 UNIX Type: L8
by (120 points)
2010-05-06 11:45:57.634 INFO Ftp(1) Command: OPTS UTF8 ON 2010-05-06 11:45:57.730 INFO Ftp(1) Response: 501 Please CLNT first. 2010-05-06 11:46:05.407 DEBUG Ftp(1) Info: Starting data transfer. 2010-05-06 11:46:05.407 INFO Ftp(1) Command: TYPE I 2010-05-06 11:46:05.502 INFO Ftp(1) Response: 200 Type set to I. 2010-05-06 11:46:05.503 DEBUG Ftp(1) Info: Accepting data connection. 2010-05-06 11:46:05.507 INFO Ftp(1) Command: PORT 10,160,18,5,212,83 2010-05-06 11:46:05.602 INFO Ftp(1) Response: 200 Port command successful.

2 Answers

+1 vote
by (147k points)
edited

It looks like something closes the FTP control connection after 3 minutes. This sometimes happens with badly behaved firewalls or routers that silently close the main (control) FTP connection because of inactivity, even though the main FTP connection is actually supposed to be inactive while the transfer is in progress (it uses a separate TCP connection).

Rebex FTP includes a workaround for this issue, but it doesn't work reliably with all FTP servers so it's disabled by default. To enable it, use this code:

C#:

client.Options |= FtpOptions.KeepAliveDuringTransfer; // send dummy NOOP commands
client.KeepAliveDuringTransferInterval = 120; // do it every 120 seconds

VB.NET:

' send dummy NOOP commands
client.Options = client.Options Or FtpOptions.KeepAliveDuringTransfer

' do it every 120 seconds
client.KeepAliveDuringTransferInterval = 120

(where "client" is your instance of Ftp object)

Does enabling this help?

by (120 points)
Unfortunately this doesn't fix the problem. I still get the same error. The logs also look identical as well.
by (147k points)
Looking at the log again (it's hard to read in the comments section, please mail it to support@rebex.net next time or edit your original question to include it), it seems I was mistaken - the control connection is not closed after 3 minutes, but after 3 seconds, which means the KeepAliveDuringTransfer is not useful in this case. Sorry!
by (147k points)
Are you actually able to upload the file using any other FTP client, like the Windows command line "ftp" utility? This actually looks like something not related to the FTP client, because closed control connection is not normal server behavior.
by (120 points)
I think that you're right. This particular FTP server doesn't seem to be acting normal. I think what I'm going to do is to add a check in my exception handling to see how many bytes were sent. And if that number matches the file size, I'll just ignore this specific error.
by (147k points)
OK, this looks like a usable workaround. In case of this failure (check FtpException's Status property), connect again, determine the uploaded file size and if it matches, then continue.
by (120 points)
Hi Lukas, Indeed, it appears that our problem is caused by something else. We've done several traces using the ftp log facility and Ethereal. We've seen this kind of problem before when we developed our own in-house protocol working with Dot Net sockets. It is necessary to set the Linger option on both the host and client side. Otherwise, what Dot Net CF sees at the end of a successful transmission is a case where both the RST and FIN flags are set at once, which CF does not handle gracefully. We handled this successfully by catching Net.IO exceptions in addition to system exceptions.
by (147k points)
Thanks James! Although most of our clients using .NET CF don't report this issue, some of them actually did recetly. You definitely saved us some time investigating this. We will implement this and mail you our development build of Rebex FTP to give it a try!
by (120 points)
Thanks for the hat-tip, Lukas. If you'll email me directly, I can supply some code snippets that worked for us with references to the MSDN docs. We haven't been bothered with those symptoms since implementing the changes. Hopefully they'll work for you. You can email me at jwwf[at]worldinfo.com. I'll be glad to send them along.
0 votes
by (140 points)
edited

I'm having this exact same problem with a specific FTP Server and have tried the solution to check the remote file size using GetFileLength. However when I do this I get the below exception:

Cannot send command to the server because the response for previous one was not received. at Rebex.Net.Ftp.BDqbPE(FtpState ) at Rebex.Net.Ftp.BQDrolZ(String , String ) at Rebex.Net.Ftp.AqUDtSZ(String ) at Rebex.Net.Ftp.GetFileLength(String remotePath)

Anyone have any ideas?

...