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.
HTTP Timeouts
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
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
> 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
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
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?
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?
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
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.
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.
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
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
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