question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

issue with Active Mode, cannot reuse the ActivePorts, then throw exception

See original GitHub issue

FluentFTP Version: reproduced on v40/v39/v38 Framework: reproduced on .NET4 and .NET6 FTP Server: reproduced on build-in FTP From Microsoft IIS and FileZilla Server FTP Client OS: reproduced on Microsoft Window 7 and Ubuntu 18.04 FTP Server OS: reproduced on Microsoft Windows Server 2016


Dear team,
Hello. Passive Mode is used in many situations, as far as we know. However, in the recent projects, we have to use the Acive Mode and limit the usage with ports rang.

Simple source code to reproduce this issue:

var ftpClient = new FluentFTP.FtpClient();
ftpClient.Host = "[[replace your ftp server ip here pls]]";
ftpClient.Port = 21;
ftpClient.Config.DataConnectionType = FluentFTP.FtpDataConnectionType.PORT;
ftpClient.Config.ActivePorts = new int[] { 8082 };

ftpClient.UploadFile(@"D:\0.jpg", "/0.jpg", FluentFTP.FtpRemoteExists.Overwrite, true);
ftpClient.UploadFile(@"D:\1.jpg", "/1.jpg", FluentFTP.FtpRemoteExists.Overwrite, true);
ftpClient.UploadFile(@"D:\2.jpg", "/2.jpg", FluentFTP.FtpRemoteExists.Overwrite, true);

Only the 0.jpg would be uploaded successfully. The subsequent files would throw the excpetion:

No valid active data port available!

This exception was originally thrown at this call stack:
    FluentFTP.FtpClient.StartListeningOnPort(FluentFTP.FtpDataStream)
    FluentFTP.FtpClient.OpenActiveDataStream(FluentFTP.FtpDataConnectionType, string, long)
    FluentFTP.FtpClient.OpenDataStream(string, long)
    FluentFTP.FtpClient.OpenWrite(string, FluentFTP.FtpDataType, long)

Logs from FluentFTP:

# Connect()
Status:   Connecting to ***:21
Response: 220-FileZilla Server 0.9.60 beta
Response: 220-written by Tim Kosse (tim.kosse@filezilla-project.org)
Response: 220 Please visit https://filezilla-project.org/
Status:   Detected FTP server: FileZilla
Command:  USER ***
Response: 331 Password required for ***
Command:  PASS ***
Response: 230 Logged on
Command:  FEAT
Response: 211-Features:
Response: MDTM
Response: REST STREAM
Response: SIZE
Response: MLST type*;size*;modify*;
Response: MLSD
Response: UTF8
Response: CLNT
Response: MFMT
Response: EPSV
Response: EPRT
Response: 211 End
Status:   Text encoding: System.Text.UTF8Encoding+UTF8EncodingSealed
Command:  OPTS UTF8 ON
Response: 202 UTF8 mode is always enabled. No need to send this command.
Command:  SYST
Response: 215 UNIX emulated by FileZilla
Status:   Listing parser set to: Machine

# UploadFile("D:\0.jpg", "/0.jpg", Overwrite, True, None)

# FileExists("/0.jpg")
Command:  SIZE /0.jpg
Response: 550 File not found

# DirectoryExists("/")

# OpenWrite("/0.jpg", Binary)

# GetFileSize("/0.jpg")
Command:  SIZE /0.jpg
Response: 550 File not found
Command:  TYPE I
Response: 200 Type set to I

# OpenActiveDataStream(PORT, "STOR /0.jpg", 0)
Command:  PORT 127,0,0,1,31,146
Response: 200 Port command successful
Command:  STOR /0.jpg
Response: 150 Opening data channel for file upload to server of "/0.jpg"
Status:   Disposing FtpSocketStream...
Response: 226 Successfully transferred "/0.jpg"

# UploadFile("D:\1.jpg", "/1.jpg", Overwrite, True, None)

# FileExists("/1.jpg")
Command:  SIZE /1.jpg
Response: 550 File not found

# DirectoryExists("/")

# OpenWrite("/1.jpg", Binary)

# GetFileSize("/1.jpg")
Command:  SIZE /1.jpg
Response: 550 File not found

# OpenActiveDataStream(PORT, "STOR /1.jpg", 0)
Unhandled exception. FluentFTP.FtpException: Error while uploading the file to the server. See InnerException for more info.
 ---> System.Exception: No valid active data port available!

Then, if we change the code (add one more port) From Config.ActivePorts = new int[] { 8082 }; To Config.ActivePorts = new int[] { 8082, 8081 }; and restart the application, the first file 0.jpg and second file 1.jpg would be uploaded successfully but subsequent files.

Therefore, we can call UploadFile times as count(Config.ActivePorts) only.

As you see, each time we call UploadFile method, FluentFTP would bind and listen to a new port. Due to cannot reuse old one , and then the ports set by the Config.ActivePorts will be used up soon.


What other things that we’ve tried already and have no luck:

  1. change Config.SocketKeepAlive
  2. change Config.DisconnectWithShutdown
  3. change Config.DisconnectWithQuit
  4. call Disconnect after UploadFile and Connect again
  5. call Disconnect and Dispose after UploadFile and recreate and reconnect again
  6. try to add code m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); to FtpSocketStream::Listen method.

Looking forward your reply and ideas. Thanks so much 😃

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
DoraemonYucommented, Sep 21, 2022

Dear @FanDjango and @robinrodricks , It now work under both .Net Framewrok and .Net Core runtime. Cheer!

Thanks again for you && Have a good day 😃

1reaction
FanDjangocommented, Sep 20, 2022

Thanks once again for the excellent diagnosis.

I found the place: private void CheckResult(SocketAsyncEventArgs args) {...}

Added the needed .Close() and tested it with .NET 6.

Once it is merged, you can test it too.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Plain FTP + active mode bug
Passive mode was/is working flawlessly. I tested with another server on a hosting (pureftpd), passive or active, absolutely no problem (with FZ ...
Read more >
Exception handling strategy - reuse exception codes
Always handle Unchecked Exceptions as close to their source as possible but avoid creating them, they are an inherently unsafe programming ...
Read more >
Are there legitimate reasons for returning exception objects ...
If it is never thrown then it's not an exception. ... I like to think of throwing an exception as a "super return"...
Read more >
Java virtual machine custom properties
If the custom property is not present in the list of already defined custom properties, create a new property. Then, enter the property...
Read more >
Break on exceptions that are not thrown intentionally - Studio
Hi, It would be nice to have an additional option for debugging that breaks on exceptions that are not thrown intentionally.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found