Koder Posted April 17, 2006 Posted April 17, 2006 InetGet() never needed a long pause before @InetGetBytesRead would work properly, I normally use 50 milliseconds. Now it needs at about 500. Why would @InetGetBytesRead return -1 if @InetGetActive is 1? In my script I check the files size (for a progress bar), then download the file. This works with NO problems whatsoever in build 118. Increasing the Sleep() fixes the problem, but how do I know it will work on other machines? A timing problem could be different on different machines. Would a slower Inet connection need a longer sleep time? Here's a cleaned up fragment. The error occurs at $LastBytes = @InetGetBytesRead, which in beta 119 reports -1 (if not paused long enough). For $i = 1 to $count $URL = "FTP:\\Ftp.URL.net\path\" & $Files[$i] $size = InetGetSize($URL) If @error == 1 Then ; report error msg(0,0,"Error: " & $Files[$i]) ExitLoop EndIf ProgressSet(0, "", "") ; Send FTP command to download file $rc = InetGet($URL, $Local & "\" & $Files[$i], 0, 1) If @error == 1 Then msg(0,0,"Error: " & $Files[$i]) Exit(1) EndIf Sleep(50); Error occurs if this sleep is too short... never needed to be any longer than 0 (zero) While @InetGetActive Sleep(10) $LastBytes = @InetGetBytesRead ; Reports -1 if sleep() is too short, but not in 118 If @InetGetBytesRead == -1 Then MsgBox(16, 0, "Download error!" & @CR & @InetGetBytesRead & @CR & $Files[$i]) ExitLoop EndIf ProgressSet((@InetGetBytesRead / $size) * 100, "", "") Wend Next Thanks! Rick
Valik Posted April 18, 2006 Posted April 18, 2006 (edited) This block of code is pointless for two reasons:; Send FTP command to download file $rc = InetGet($URL, $Local & "\" & $Files[$i], 0, 1) If @error == 1 Then msg(0,0,"Error: " & $Files[$i]) Exit(1) EndIfFirst reason, InetGet() can set @error to more than just 1. Also, the error codes of InetGet() are undocumented and should not be used. If you need to know if InetGet() succeeded or not, use the return value.Second reason, calling InetGet() with the background mode parameter won't cause @error to be set at all. It also won't return any other value except 1.To answer your question, the download hasn't started. @InetGetBytes is set to -1 from the time InetGet() is started up until the function establishes communication wit the remote host. Then it will be set to 0 and the download loop is started. So that means there is a flaw in your logic. You shouldn't be checking the value of @InetGetBytesRead and treating it as an error condition while a download is active. If a download is active, then it's still active and no error has occurred yet. The value returned by @InetGetBytesRead only denotes that an error occurred connecting to the remote host after the download is terminated (meaning @InetGetActive is no longer true).I chalk this up to mis-leading documentation.You don't need the Sleep() at all and the last block of code should be:While @InetGetActive Sleep(10) $LastBytes = @InetGetBytesRead; Reports -1 if sleep() is too short, but not in 118 If $LastBytes = -1 Then $LastBytes = 0 ProgressSet(($LastBytes / $size) * 100, "", "") Wend If @InetGetBytesRead = -1 Then MsgBox(16, 0, "Download error!" & @CR & @InetGetBytesRead & @CR & $Files[$i]) EndIfI'm inclined to remove the -1 altogether. If a user knows a download is supposed to occur, then checking if @InetGetBytesRead = 0 after their @InetGetActive loop should be a signal the download has occurred. Otherwise, as demonstrated in the revised fragment above, we are going to have to manually catch a -1 byte count and convert it to 0 to make sure progress calculations don't end up being weird.Edit: On second thought, I just thought of a way to change the code so that your code will continue to work without the Sleep() statement. Edited April 18, 2006 by Valik
Koder Posted April 18, 2006 Author Posted April 18, 2006 (edited) Hey, thanks for the info, I would have kept using @error and never nocticed a download problem until later. Shouldn't @InetGetBytesRead return -1 only when an error has occurred? and return 0 while the connection is still being negotiated? If the connection later fails, -1 would be informative. Otherwise @InetGetBytesRead = -1 means different things during the course of the download. I could check for -1 at the start of the loop, but then what if it's a real error? Does @InetGetActive change to 0 at the same time? With @InetGetBytesRead = 0 until the connection starts, there is no special case required and @InetGetBytesRead can be used directly without being cleaned up from -1. So the real question is, what does a real error look like (if it occurs during a download that starts normally)? Ok, I've coded the answer to my question below and yes, this does work. But I still have no way of knowing what a real error will look like. Do I know that @InetGetActive wil change to 0 when my network cable is pulled out? $rc = InetGet($URL, $Local & "\" & $Files[$i], 0, 1) while @InetGetActive $LastBytes = @InetGetBytesRead if @InetGetActive == 1 AND $LastBytes == -1 Then ; Not an Error? ; server still connecting? $LastBytes = 0; prevents progress bar from using -1 ElseIf @InetGetActive == 0 AND $LastBytes == -1 Then ; Real error? ; Hard to test, pull the NIC cable on a large file? exitloop Endif ProgressSet(($LastBytes / $size) * 100, "", "") wend if @InetGetBytesRead == -1 Then ; Real error endif By the way this code fragment is intentionally, unnecessarily complicated. Valik, your example is better. I'm only complaining a bit about -1 not being a real error. Thanks! Rick Edited April 18, 2006 by Koder
Valik Posted April 18, 2006 Posted April 18, 2006 Essentially, the correct way to write a download loop is (in pseudo-code): $size = InetGetSize() InetGet() While @InetGetActive ; Wait for download to finish WEnd If @InetGetBytesRead <> $size Then MsgBox(4096, "", "Error occurred") Checking against the hard-coded value of -1 is the wrong thing to do and always has been. You really should be checking that the size after the download is equal to the size of the file. That being said, I'm going to modify the code so that it sets @InetGetBytesRead to 0 up until the download starts. Once the download starts, then it will begin counting the bytes downloaded. If an error occurs during the middle of the download, @InetGetBytesRead will not be reset to -1, it will be the total bytes read up until the point of the error. If an error occurs before the download actually starts, @InetGetBytesRead will be set to -1 to signify an error. This change should allow your original code to continue to work without any sleep statements between InetGet() and the While loop. In any case, the example I provided above shows the correct way to monitor a download regardless of which version of AutoIt you're using. I will also add that example to the documentation.
Gene Posted April 19, 2006 Posted April 19, 2006 Essentially, the correct way to write a download loop is (in pseudo-code): $size = InetGetSize() InetGet() While @InetGetActive ; Wait for download to finish WEnd If @InetGetBytesRead <> $size Then MsgBox(4096, "", "Error occurred") Checking against the hard-coded value of -1 is the wrong thing to do and always has been. You really should be checking that the size after the download is equal to the size of the file. That being said, I'm going to modify the code so that it sets @InetGetBytesRead to 0 up until the download starts. Once the download starts, then it will begin counting the bytes downloaded. If an error occurs during the middle of the download, @InetGetBytesRead will not be reset to -1, it will be the total bytes read up until the point of the error. If an error occurs before the download actually starts, @InetGetBytesRead will be set to -1 to signify an error. This change should allow your original code to continue to work without any sleep statements between InetGet() and the While loop. In any case, the example I provided above shows the correct way to monitor a download regardless of which version of AutoIt you're using. I will also add that example to the documentation. Hi Valik, While you are into that (I haven't researched this because I didn't think of it until I was reading your post) is there anything that can be done to allow (if it isn't already available) a progress bar reflecting the download or even a simple update of bits/bytes downloaded? If that isn't possible, is there a way (that the average Joe could come up with) to do something similar with existing capabilities. Notice I didn't ask what it is. Gene [font="Verdana"]Thanks for the response.Gene[/font]Yes, I know the punctuation is not right...
Moderators SmOke_N Posted April 19, 2006 Moderators Posted April 19, 2006 Hi Valik,While you are into that (I haven't researched this because I didn't think of it until I was reading your post) is there anything that can be done to allow (if it isn't already available) a progress bar reflecting the download or even a simple update of bits/bytes downloaded? If that isn't possible, is there a way (that the average Joe could come up with) to do something similar with existing capabilities. Notice I didn't ask what it is. Gene http://www.autoitscript.com/forum/index.ph...ndpost&p=141934 Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.
Valik Posted April 19, 2006 Posted April 19, 2006 Hi Valik,While you are into that (I haven't researched this because I didn't think of it until I was reading your post) is there anything that can be done to allow (if it isn't already available) a progress bar reflecting the download or even a simple update of bits/bytes downloaded? If that isn't possible, is there a way (that the average Joe could come up with) to do something similar with existing capabilities. Notice I didn't ask what it is. Gene That's the kind of stuff that gets done in the While loop and far exceeds the scope of a downloading function. That's also the reason there is a macro for getting the number of bytes downloaded and another function for getting the size from the server. It's trivial to calculate all that stuff.
Valik Posted April 19, 2006 Posted April 19, 2006 (edited) Just a quick update, I've made the changes to fix this issue and things should be working just like they were previously with the new code. If an error occurs, @InetGetBytesRead will be set to -1 unconditionally. This includes setting the value to -1 when an error occurs in the middle of a file transfer. Previously I stated the counter would be left alone but that is not how AutoIt has ever worked so I'm not going to change that behavior. Once I upload these changes, the function should work identical to previous versions. I have more work to do on InetGet() but the changes should be in the next version of AutoIt and no later than 2 versions away. Edited April 19, 2006 by Valik
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now