Link to home
Start Free TrialLog in
Avatar of steveuci
steveuci

asked on

FTP using INET control - Executing "LS" / "DIR" times out on empty directories

I seem to have run into a weird problem with the INET control in VB6 and am unable to troubleshoot further.   I hope someone here can answer why this may be happening.    

I am using the Inet control to perform a directory change (CD) and a directory listing (LS or DIR).   These operations work fine and are very quick.  However, when attempting to execute an LS or DIR on a remote directory that has nothing in it, the Inet control seems to time out and take 60 seconds to issue a ResponseCompleted callback to the StateChanged event.  This is about 59 seconds too long!


Basic steps to reproducing:

1) FTP server using IIS on a remote machine on the LAN (which is sitting next to me)

2) Run VB6 + INET code on another machine on the same LAN (which is also sitting next to me)

3) Upon Form_Load, initialize URL, Username, Password, Port (21), Protocol (icFTP).

4) If there is a file and/or subdirectory in the root of the login,
Inet1.Execute Inet1.URL, "LS"
will quickly fire an icResponseCompleted StateChanged event, and a followup GetChunk works no problem to show the directory contents.

5) If there is NO file and NO subdirectory in the root of the login,
Inet1.Execute Inet1.URL, "LS"
will take exactly 60 seconds (way too long!) to fire the icResponseCompleted StateChanged event.

Here is a breakdown of the StateChanged tracing to show where the INET control takes its sweet time upon asking Inet to execute LS or DIR:

Requesting
Request Sent
Receiving Response
Response Received
Requesting
Request Sent
Receiving Response
Response Received
Requesting
Request Sent
Receiving Response
Response Received
<------ 60 seconds elapses
Reponse Completed


Any ideas on how to fix this is greatly appreciated!  Thanks!
 
Avatar of edwardiii
edwardiii

Hi, steveuci.

Per the code at the URL: (http://www.vbcity.com/forums/topic.asp?tid=96601&#RID304009), could you try
using something like:

     With Inet1
          .Url = strYourUrl
          'handle your ftp site login code here
          .Execute, "Dir"
         
          DoEvents
          freshData = Inet1.GetChunk(1024,icString)
          constructData = constructData & freshData
     Loop Until Len(freshData) = 0

In other words if you stop processing when GetChunk returns no data, do you still get the 1 minute timeout?

Avatar of steveuci

ASKER

edwardiii,

I'm afraid the problem is that the actual Inet control is still in "executing" mode for a whole minute, doing nothing, and does NOT return control to my application until the 1 minute has elapsed.    
You're correct.  I've noticed in routines posted by Idle Mind (Genius-level expert in this forum), the MSDN website, etc., Inet routines are to include a DoEvents loop with an associated process housed in the Inet control's StateChanged event.  Can you please post the code you've got 1) that fires the FTP actions and 2)in your Inet's StateChanged event?
If I'm reading the Spanish descriptives correctly this site (http://mailgate.supereva.it/es/es.comp.lenguajes.visual-basic/msg12740.html) presents a solution to the empty directory that I believe mirrors your own.  The key code seems to involve:

     ERROR_NO_MORE_FILES

See the accepted answer to this EE post (https://www.experts-exchange.com/questions/20106676/FTP-in-VB-Inet-and-various-functionalities.html?query=ERROR_NO_MORE_FILES&topics=93) for full details on this API-based solution.
Here are the main code fragments from my test app.   There is also a listbox List1 on the form to show the tracing of StateChanged events fired.

Private Sub Command1_Click()
   
    Inet1.Execute Inet1.URL, "DIR"
    List1.AddItem "Control returned from .Execute"
   
End Sub

Private Sub Inet1_StateChanged(ByVal State As Integer)

    Select Case State
        Case icNone
            List1.AddItem "None"
        Case icResolvingHost
            List1.AddItem "Resolving Host..."
        Case icHostResolved
            List1.AddItem "Host Resolved..."
        Case icConnecting
            List1.AddItem "Connecting..."
        Case icConnected
            List1.AddItem "Connected..."
        Case icRequesting
            List1.AddItem "Requesting..."
        Case icRequestSent
            List1.AddItem "Request Sent..."
        Case icReceivingResponse
            List1.AddItem "Receiving Response..."
        Case icResponseReceived
            List1.AddItem "Response Received..."
        Case icDisconnecting
            List1.AddItem "Disconnecting..."
        Case icDisconnected
            List1.AddItem "Disconnected..."
        Case icError
            List1.AddItem "Error... " & Trim(CStr(Inet1.ResponseCode)) & ": " & Inet1.ResponseInfo
        Case icResponseCompleted
            List1.AddItem "Response Completed..."
        Case Else
            List1.AddItem "Unknown response: " & State
    End Select

End Sub


Upon clicking Command1, List1 gets populated with the following:

Requesting
RequestSent
ReceivingResponse
Responce Received
Requesting
RequestSent
ReceivingResponse
Responce Received
Requesting
RequestSent
ReceivingResponse
Responce Received
Control returned from .Execute
Response Completed...

The 60 second delay takes place just before the "Control returned from .Execute".


I am hoping to get this to work using the Inet control.  I'm sure converting the app to use direct WININET.DLL API will help (and that is a good suggestion), but that is some code rewriting I'd like to avoid unless it's my only choice.
ASKER CERTIFIED SOLUTION
Avatar of edwardiii
edwardiii

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Well I do have loops, but control is never given to the loops because the .Execute method of the Inet control is hogging program execution for 60 seconds.   It's not like I'm waiting for .StillExecuting to be false, I can't even test for that in this case.

BUT, given the nature of what I'm doing (small 1K files), setting a shorter timeout as you mentioned is probably the best solution short of figuring out exactly why it's hanging up for 60 seconds, and short of additional rewriting to a different API.

I'll leave this question open for a day to see if someone chimes in with a better solution, otherwise that'll have to do.   Thanks!