Page 1 of 1

Posted: Mon Jun 10, 2002 6:25 pm
by BackupUser
Restored from previous forum. Originally posted by Justin.

I want to make a program that downloads some files from internet, i use the wininet.api, sometimes the server stops sending data and the program will hang in the Internetreadfile waiting forever for a response.

Wich would be the best approach to set a timeout and have the ability to retry or skip the file?, has anyone tried something similar?

maybe using 2 threads, one that downloads and another to check if the data is being recieved?

or using a callback function?, the wininet has this feature:
http://msdn.microsoft.com/library/en-us ... LLBACK.asp

i don't understand some parameters of that function, maybe monitoring the INTERNET_STATUS_RESPONSE_RECEIVED message?

thanks for any help.

Posted: Mon Jun 10, 2002 6:36 pm
by BackupUser
Restored from previous forum. Originally posted by PB.

> I want to make a program that downloads some files from internet, i use the
> wininet.api, sometimes the server stops sending data and the program will
> hang in the Internetreadfile waiting forever for a response.

Try the following tip and see if the files being downloaded still hang... if they
don't, then your current download routine could just be a bit buggy or something.

viewtopic.php?t=628

PB - Registered PureBasic Coder

Posted: Mon Jun 10, 2002 6:58 pm
by BackupUser
Restored from previous forum. Originally posted by Justin.

Thanks, maybe i can get some ideas from that thread.

But the problem is that i need to do a POST request, sending some special data and a refer to get the file, i don't think that function can do post requests.

Any ideas using the wininet functions?

Posted: Tue Jun 11, 2002 10:28 am
by BackupUser
Restored from previous forum. Originally posted by Justin.

Maybe a more direct question..

Does anybody know what the parameter dwContext means in this callback function?

INTERNET_STATUS_CALLBACK
This function is a prototype for an application-defined status callback function.

typedef void (CALLBACK *INTERNET_STATUS_CALLBACK) (
HINTERNET hInternet,
DWORD_PTR dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength
);

Parameters
hInternet
[in] Handle for which the callback function is being called.

dwContext
[in] Address of an unsigned long integer value that contains the application-defined context value associated with the hInternet parameter.


dwInternetStatus
[in] Unsigned long integer value that contains the status code that indicates why the callback function is being called. The following table shows the values for the dwInternetStatus parameter.

Posted: Wed Jun 12, 2002 8:25 pm
by BackupUser
Restored from previous forum. Originally posted by Justin.

Thanks to the thread PB suggested i figured out how to do it using 2 threads.

I think it is better than the example in that thread because if i undesrtanded well the timeout there is the maximun time that the whole download process can take (wich timeout do you use for a 50MB file?)

Here the timeout is the max time without recieving data, a timeout of 60 sec means that if no data is recieved during 60 sec the process will stop.

The example downloads a web page to a string, it can be easily modificated to download a binary file to disk.

There is a 5 sec timeout, if you don't click Ok during that time the download stops.

#INTERNET_OPEN_TYPE_DIRECT = 1
#INTERNET_DEFAULT_HTTP_PORT = 80
#INTERNET_SERVICE_HTTP = 3
#INTERNET_FLAG_NO_CACHE_WRITE = 67108864

#TimeOut = 5000

Global GotData, TimedOut, strread$

;Downloads the file(1Kb each time)
Procedure I_ReadFile(openreqhandle)
buf$=Space(1024)
Repeat
InternetReadFile_(openreqhandle,@buf$,1024,@bread)
strread$=strread$+Left(buf$,bread)
MessageRequester(Str(bread),buf$,0)
Until bread=0
GotData = #TRUE
EndProcedure

;Checks every milliseconds if the data recieved has changed
Procedure Timeout(millisecs)
Repeat
oldstrread$=strread$
Delay(millisecs)
Until oldstrread$=strread$
TimedOut = #TRUE
EndProcedure

host.s="yahoo.com" ;host
geturl.s="/" ;rest of url to download

;initialize internet functions (no error checking)
tophandle = InternetOpen_("PB",#INTERNET_OPEN_TYPE_DIRECT,"","",0)
connecthandle = InternetConnect_(tophandle,host,#INTERNET_DEFAULT_HTTP_PORT,"","",#INTERNET_SERVICE_HTTP,0,0)
openreqhandle = HttpOpenRequest_(connecthandle,"GET",geturl,"","",0,#INTERNET_FLAG_NO_CACHE_WRITE,0)
sendreq = HttpSendRequest_(openreqhandle,"",0,"",0)

TimedOut = #FALSE
GotData = #FALSE

TimThreadID = CreateThread(@Timeout(), #TimeOut)
DownThreadID = CreateThread(@I_ReadFile(), openreqhandle)

Repeat
Until TimedOut Or GotData

;close internet handles
InternetCloseHandle_(openreqhandle)
InternetCloseHandle_(connecthandle)
InternetCloseHandle_(tophandle)

If TimedOut
MessageRequester("","Timeout",0)
EndIf

If GotData
MessageRequester("","All data recieved.",0)
EndIf

If TimedOut = #FALSE : KillThread(TimThreadID) : EndIf
If GotData = #FALSE : KillThread(DownThreadID) : EndIf