Announcement

Collapse

Maintenance

The forum could be offline for 30-60 minutes in the very near future for maintenance (said 3pm Pacific). I was behind on getting this notice. I do apologize.
See more
See less

URLDownloadToFile vs TCP

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • URLDownloadToFile vs TCP

    I use TCP code to download updates to the EXEs of apps I've posted in the Source Code forums. I use TCP because it makes it possible to show a progress bar for the download operation. Especially when files are large and download times are long, it's something users appreciate.

    Other than that advantage, is there any reason why I would pick TCP over URLDownloadToFile?

    Searching online I've not found any discussions that discourage the use of URLDownloadToFile.

    When downloading a number of small files, a display of how many files have been downloaded could be enough of a progress indication to warrant not using the slightly more complicated TCP code.

  • #2
    > I use TCP because it makes it possible to show a progress bar for the download operation.

    You can also use a progress bar with URLDownloadToFile:

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE ONCE "windows.inc"
    #INCLUDE ONCE "urlmon.inc"
    
    FUNCTION PBMAIN
    
       ' // Create an instance of our implementation of the IBindStatusCallback interface
       LOCAL pfnCB AS IBindStatusCallbackImpl
       pfnCB = CLASS "CBindStatusCallBackImpl"
    
       ' // Do the download
       UrlDownloadToFile(NOTHING, "http://www.powerbasic.com/support/pbforums/", _
          EXE.PATH$ & "test.html", 0, pfnCB)
    
    END FUNCTION
    
    ' ========================================================================================
    ' Custom implementation of the IBindStatusCallback interface
    ' ========================================================================================
    
    $CLSID_CBindStatusCallBackImpl = GUID$("{8FFDCF89-1C26-454A-94AC-6214E21513E0}")   ' --> change me if needed
    
    CLASS CBindStatusCallBackImpl $CLSID_CBindStatusCallBackImpl AS COM   ' MUST be AS COM to avoid dead code removal
    
    INTERFACE IBindStatusCallbackImpl $IID_IBindStatusCallback
    
       INHERIT IUnknown
    
       ' =====================================================================================
       METHOD OnStartBinding ( _                            ' VTable offset = 12
         BYVAL dwReserved AS DWORD _                        ' __in DWORD dwReserved
       , BYVAL pib AS IBinding _                            ' __in IBinding *pib
       ) AS LONG                                            ' HRESULT
    
         ' Put your code here
    
       END METHOD
       ' =====================================================================================
    
       ' =====================================================================================
       METHOD GetPriority ( _                               ' VTable offset = 16
         BYREF pnPriority AS LONG _                         ' __out LONG *pnPriority
       ) AS LONG                                            ' HRESULT
    
         ' Put your code here
    
       END METHOD
       ' =====================================================================================
    
       ' =====================================================================================
       METHOD OnLowResource ( _                             ' VTable offset = 20
         BYVAL reserved AS DWORD _                          ' __in DWORD reserved
       ) AS LONG                                            ' HRESULT
    
         ' Put your code here
    
       END METHOD
       ' =====================================================================================
    
       ' =====================================================================================
       METHOD OnProgress ( _                                ' VTable offset = 24
         BYVAL ulProgress AS DWORD _                        ' __in ULONG ulProgress
       , BYVAL ulProgressMax AS DWORD _                     ' __in ULONG ulProgressMax
       , BYVAL ulStatusCode AS DWORD _                      ' __in ULONG ulStatusCode
       , BYREF szStatusText AS WSTRINGZ _                   ' __in LPCWSTR szStatusText
       ) AS LONG                                            ' HRESULT
    
         ' Put your code here
    
       END METHOD
       ' =====================================================================================
    
       ' =====================================================================================
       METHOD OnStopBinding ( _                             ' VTable offset = 28
         BYVAL hresult AS LONG _                            ' __in HRESULT hresult
       , BYREF szError AS WSTRINGZ _                        ' __in LPCWSTR szError
       ) AS LONG                                            ' HRESULT
    
         ' Put your code here
    
       END METHOD
       ' =====================================================================================
    
       ' =====================================================================================
       METHOD GetBindInfo ( _                               ' VTable offset = 32
         BYREF grfBINDF AS DWORD _                          ' __out DWORD *grfBINDF
       , BYREF pbindinfo AS BINDINFO _                      ' __in_out BINDINFO *pbindinfo
       ) AS LONG                                            ' HRESULT
    
         ' Put your code here
    
       END METHOD
       ' =====================================================================================
    
       ' =====================================================================================
       METHOD OnDataAvailable ( _                           ' VTable offset = 36
         BYVAL grfBSCF AS DWORD _                           ' __in DWORD grfBSCF
       , BYVAL dwSize AS DWORD _                            ' __in DWORD dwSize
       , BYREF pformatetc AS FORMATETC _                    ' __in FORMATETC *pformatetc
       , BYREF pstgmed AS STGMEDIUM _                       ' __in STGMEDIUM *pstgmed
       ) AS LONG                                            ' HRESULT
    
         ' Put your code here
    
       END METHOD
       ' =====================================================================================
    
       ' =====================================================================================
       METHOD OnObjectAvailable ( _                         ' VTable offset = 40
         BYREF riid AS GUID _                               ' __in REFIID riid
       , BYVAL punk AS IUnknown _                           ' __in IUnknown *punk
       ) AS LONG                                            ' HRESULT
    
         ' Put your code here
    
       END METHOD
       ' =====================================================================================
    
    END INTERFACE
    
    END CLASS
    ' ========================================================================================
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment


    • #3
      With URLDownloadToFIle, you ARE using TCP

      TCP is a communications protocol.
      URLDownloadtoFIle is an API call which encapsulates a number of things including TCP communications

      It's sort of like using DDT v SDK, the former just encapsulates the latter and makes it quicker and easier than rolling your own code to do the same thing from scratch.

      Comment


      • #4
        Another one,
        kind of lo level but will give another view angle...

        Comment


        • #5
          Thanks Jose/Pierre, I seem to recall seeing something about using the IBINDxxx solution from years ago. Thanks for the examples!

          Kurt, yes, I was aware of URLDownloadToFile's underpinnings but I just wondered if the encapsulation was completely acceptable to use - stable, no side effects, any odd behavior, any constraints, etc.or if the implementation had issues that made using the PowerBASIC TCP commands more desirable. Your description of DDT vs SDK is appropriate.




          Comment


          • #6
            A side question ... when you use URLDownloadToFile, where the local path is an existing file, does the API replace the target file only if it has a successful download or does it replace the target file even if the download fails?

            For example, does it download the URL as a *.tmp file, then delete the existing file and then rename the *.tmp to the target file name, where the existing file is not destroyed unless the download is successful?

            Or, does it just automatically start rewriting over the old file even if the download is unsuccessful.

            I'll go try and test that ...

            Comment


            • #7
              Well, on a quick test, if the URLPath does not exist, the local file is not overwritten - remains untouched in my test.

              But, I didn't test what happens if the download is interrupted. I'll see if I can do that too ...

              Comment


              • #8
                Gary,
                Have you tried downloading with only TCP code from a HTTPS site?
                I can't remember all the problems, but I switched to Jose's code a few years ago.
                How long is an idea? Write it down.

                Comment


                • #9
                  There can be limitations. Web sites can be configured so the URLDownloadToFile won't be accepted to prevent automatic downloads of data. Not an issue in your case.

                  Comment


                  • #10
                    Howdy, Mike!
                    No, I've not tried that. All of my needs have been to downloaded stuff from garybeene.com. You had troubles with TCP? Any more details you can think of would be useful!

                    John,
                    What do you mean by "automatic"? In such a case, would the TCP or BIND approaches both work?

                    Comment


                    • #11
                      I believe the problem is web sites that direct redirect http to https or that https or https argument isn't available.
                      Port 80 - get error 302.
                      Port 443 - get error 400.
                      Code:
                      #DIM ALL
                      FUNCTION PBMAIN AS LONG
                        ? Test(80,"xyz.com","/folder/beene.txt")
                      END FUNCTION
                      
                      FUNCTION test(PortNumber AS LONG, Site AS STRING, File AS STRING)  AS STRING
                         LOCAL buffer    AS STRING
                         LOCAL temp      AS STRING
                         LOCAL i         AS LONG
                         LOCAL h         AS LONG
                         h = FREEFILE
                         TCP OPEN PORT PortNumber AT site AS #h TIMEOUT 10000
                         IF ERR THEN
                           ? USING$("TCP open error # ",ERR)
                           EXIT FUNCTION
                         END IF
                         TCP PRINT #h, "GET " & file & " HTTP/1.0"
                         TCP PRINT #h, "Accept: */*"
                         TCP PRINT #h, "Accept-Language: en-us"
                         TCP PRINT #h, "Host: " & site
                         TCP PRINT #h, "Pragma: no-cache"
                         TCP PRINT #h, "Referer: URL=http://www.me.com"
                         TCP PRINT #h, "User-Agent: webget modified 1.3 www.me.com"
                         TCP PRINT #h, ""
                         DO
                            TCP RECV #h, 4096, buffer
                            temp = temp & buffer
                         LOOP UNTIL LEN(Buffer) = 0 OR ERRCLEAR
                         TCP CLOSE #h
                         FUNCTION = temp
                      END FUNCTION
                      How long is an idea? Write it down.

                      Comment


                      • #12
                        Originally posted by Gary Beene View Post
                        Well, on a quick test, if the URLPath does not exist, the local file is not overwritten - remains untouched in my test.

                        But, I didn't test what happens if the download is interrupted. I'll see if I can do that too ...
                        If you are worried about that, why you don't use IWinttpRequest instead. I have posted many examples in this forum, that have been ignored as it happens with all COM stuff.

                        See: https://forum.powerbasic.com/forum/j...015#post612015

                        This example downloads a file in chunks, allowing to use a progress bar, and also save it only when the operation has been completed.

                        ...and the example that follows reads all the data at once.
                        Last edited by José Roca; 25 Aug 2017, 08:38 AM.
                        Forum: http://www.jose.it-berater.org/smfforum/index.php

                        Comment


                        • #13
                          Howdy, Jose!

                          Well, it's like many of the questions I ask - just wondering what the limits are on the available tools! If a simple tool will do the job, I'm happy to use it. If a better tool is needed, then I'm happy to use it too!

                          Comment


                          • #14
                            Jose,

                            off topic for a moment ...


                            On the topic of COM, I know that it's on my list to use but I just keep putting it off because most of what I do can be done with other methods. I wonder why other folks haven't jumped more on the COM bandwagon? Especially, I'd have expected the SDK advocates to be hound dogs on the topic.

                            I'm certain it's not laziness because many of us work long hours doing what we love to do. So to what do you attribute your observation that COM doesn't get the appropriate attention?

                            Comment


                            • #15
                              It is a new world of learning. Just look at the options with WinHttp. There must be COM for dummies (not you guys, me.)
                              https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

                              Gary, does your code download from a https site? Some day it may have to if google gets there way which is probably good.
                              How long is an idea? Write it down.

                              Comment


                              • #16
                                Originally posted by Gary Beene View Post
                                Jose,

                                off topic for a moment ...


                                On the topic of COM, I know that it's on my list to use but I just keep putting it off because most of what I do can be done with other methods. I wonder why other folks haven't jumped more on the COM bandwagon? Especially, I'd have expected the SDK advocates to be hound dogs on the topic.
                                Except Dominic, the SDK advocates of this forum seem to think that SDK doesn't go beyond procedural programming. I know of one that still confusses COM with OOP and has bought books about OOP programming to learn COM!

                                Originally posted by Gary Beene View Post
                                I'm certain it's not laziness because many of us work long hours doing what we love to do.
                                Maybe you will have to work less hours if you knew COM programming.

                                Originally posted by Gary Beene View Post
                                So to what do you attribute your observation that COM doesn't get the appropriate attention?
                                I don't know, although the lack of promotion by PowerBASIC, Inc. (no tutorials in the help file, no examples, no support to use it in the official PB headers files) certainly has not helped.
                                Forum: http://www.jose.it-berater.org/smfforum/index.php

                                Comment


                                • #17
                                  Jose,

                                  Yes, I think the issue for SDK and COM are the similar ...

                                  ... the lack of promotion by PowerBASIC, Inc.
                                  With the owner/inventor of the product pushing DDT, and improving it regularly, the motivation to look elsewhere was greatly diminished.

                                  Sorry, I'll get back on topic now ...

                                  Comment


                                  • #18
                                    Mike,
                                    Thanks for the example. And you may be right about https becoming mandatory eventually.

                                    Comment


                                    • #19
                                      If the Like buttons worked it would also assist to draw attention to great posts like Jose's WINHTTP Com.

                                      Comment


                                      • #20
                                        Off topic, but related:

                                        As someone did cast doubts about the convenience of using CDO, I have been able to test CDOSys with a 64 b ot Basic compiler and it works.

                                        See: https://forum.powerbasic.com/forum/u...-code-test-bed

                                        Therefore, it is safe to use CDOSys. And I mean CDOSys, not CDO 2000, CDO for Microsoft Exchange and other old components.
                                        Forum: http://www.jose.it-berater.org/smfforum/index.php

                                        Comment

                                        Working...
                                        X