Opened 11 years ago
Closed 4 years ago
#2596 closed Bug (Works For Me)
TCPRecv not returning data, and setting @error to -1
Reported by: | diegomainster@… | Owned by: | Jpm |
---|---|---|---|
Milestone: | Component: | AutoIt | |
Version: | 3.3.10.2 | Severity: | None |
Keywords: | Cc: |
Description
Hello, sorry for my english, I'm using a translator.
I would like to inform that the TCPRecv is not returning data, and are setting @error to -1. I noticed this problem in version 3.3.10.0, updated today to version 3.3.10.2 and still continues. The problem is not in my notebook because it tested in another, and not in my script, it works with version 3.3.8.1. A script to test I'm using is this:
TCPStartup() ;if I set $ip with a local address or a nearby site, such as the provider, TCPRecv works most of the time, but sometimes not $ip = TCPNameToIP('www.google.com') If @error Then erro('TCPNameToIP', @error) $tc = TCPConnect($ip, 80) If @error Then erro('TCPConnect', @error) TCPSend($tc, 'GET / HTTP/1.1' & @CRLF & 'Host: www.google.com' & @CRLF & 'Connection: close' & @CRLF & @CRLF) If @error Then erro('TCPSend', @error, 1) $tr = '' $ti = TimerInit() Do $tr &= TCPRecv($tc, 1) If @error Then erro('TCPRecv', @error, 1) If TimerDiff($ti) > 9999 Then erro('Timeout', '', 1) Until StringInStr($tr, @CRLF & @CRLF) MsgBox(0, 'Receive Header:', $tr) $tr = '' $ti = TimerInit() While 1 $tr &= TCPRecv($tc, 1480) If @error Or TimerDiff($ti) > 9999 Then ExitLoop WEnd MsgBox(0, 'Receive Content:', $tr) TCPCloseSocket($tc) Func erro($f, $e, $c = 0) MsgBox(16, 'Erro:', 'Function ' & $f & @LF & '@error = ' & $e) If $c Then TCPCloseSocket($tc) TCPShutdown() Exit EndFunc
If I call the Sleep() before TCPRecv with a greater than or equal to 500ms time (sometimes works with a shorter time), the TCPRecv returns data, and not sets @error, as in the following script:
TCPStartup() ;if I set $ip with a local address or a nearby site, such as the provider, TCPRecv works most of the time, but sometimes not $ip = TCPNameToIP('www.google.com') If @error Then erro('TCPNameToIP', @error) $tc = TCPConnect($ip, 80) If @error Then erro('TCPConnect', @error) TCPSend($tc, 'GET / HTTP/1.1' & @CRLF & 'Host: www.google.com' & @CRLF & 'Connection: close' & @CRLF & @CRLF) If @error Then erro('TCPSend', @error, 1) $tr = '' ;with sleep work Sleep(500) $ti = TimerInit() Do $tr &= TCPRecv($tc, 1) If @error Then erro('TCPRecv', @error, 1) If TimerDiff($ti) > 9999 Then erro('Timeout', '', 1) Until StringInStr($tr, @CRLF & @CRLF) MsgBox(0, 'Receive Header:', $tr) $tr = '' $ti = TimerInit() While 1 $tr &= TCPRecv($tc, 1480) If @error Or TimerDiff($ti) > 9999 Then ExitLoop WEnd MsgBox(0, 'Receive Content:', $tr) TCPCloseSocket($tc) Func erro($f, $e, $c = 0) MsgBox(16, 'Erro:', 'Function ' & $f & @LF & '@error = ' & $e) If $c Then TCPCloseSocket($tc) TCPShutdown() Exit EndFunc
Attachments (0)
Change History (52)
comment:1 Changed 11 years ago by Mat
comment:2 Changed 11 years ago by anonymous
If I test with an "IP / site" my country, the results are similar to yours, but if the "IP / site" is from another country (I think for the ping be higher), the tests I did with the changes you made, 100% @ error = -1.
Test with an "IP / site" with a higher ping. I think the problem is these new versions, as in 3.3.8.1 does not have this problem.
My test result: http://pastebin.com/rqKj0KqC
The same test in version 3.3.8.1: http://pastebin.com/fcBMNdAJ
comment:3 Changed 11 years ago by Mat
I tried it with www.gov.au as I figured it wouldn't get further away than australia. Ping() would occasionally fail with @error = 2, but would mostly return around 340ms. TCPRecv failed with -1 every time. Adding a 500ms sleep between sending and receiving works.
So TCPRecv needs to be changed to wait for data (with timeout?) or does TCPSend need to be modified to wait for a reply before returning success?
comment:4 Changed 11 years ago by diegomainster@…
I think I found a temporary solution to this problem:
If I replace the code below the first TCPRecv
If @error Then erro('TCPRecv', @error, 1)
by that:
If @error = -1 Then Sleep(100) ElseIf @error Then erro('TCPRecv', @error, 1) EndIf
the data is returned in the next call to TCPRecv. So I think @error = -1 does not mean a serious error or that the socket was closed, I think it just means that the socket is not ready to receive data.
comment:5 Changed 11 years ago by garbb
I was having the same problem. It seems that TCPRecv() is now setting @error=-1 in different situations in v3.3.10.2 than it was in v3.3.8.1. Like you say, -1 is not a fatal error, it just means that it it waiting/not ready. I tested forcibly disconnecting a connection I made with a v3.3.10.2 script using external software and got @error=10054 which is "connection reset by peer" so it is setting @error as it was in v3.3.8.1 other than the -1 thing.
comment:6 Changed 11 years ago by garbb
After experimenting with this a bit more it seems that TCPRecv() will just set @error=-1 when it has no data to return (when the tcp buffer is empty?)
This is probably why when you add a delay after sending with TCPSend() you will not get @error=-1. You have allowed enough time to pass for the server to return some data and the TCP buffer to be filled.
So really the issue here is an undocumented change to the way that TCPRecv() works (what it sets @error to in what cases)
If you simply change your error handling to only check for @error>0 after a TCPRecv call then it should work as in v3.3.8.1
comment:7 Changed 11 years ago by musiqueGraeme
I have found the same problem with UDPRecv returning the error -1 when empty. I have set the error handling to ignore error=-1.
comment:8 Changed 11 years ago by anonymous
Is it possible to revert this behavior back to the v3.3.8.1 state? It was useful in detecting a closed socket on the other end. Thank you.
comment:9 Changed 11 years ago by anonymous
TCPRecv is horribly degraded by new update version. Setting @ERROR for blank returns has no practical use as far as I can tell, and only harms the process. TCPRecv needs to be able to detect client side closed sockets as older versions of TCPRecv were able to do. Don't know why @error -1 is set for blank returns and if it needs to be that way then fine, (have no idea why), but please let there be some kind of error setting that can detect client side closed sockets. @error -1 for detecting client side closed sockets was invaluable to TCPRecv heavy scripts and I can not use newer versions of Autoit3 in those scripts because the older TCPRecv is many times over more efficient than the newer versions.
comment:10 Changed 11 years ago by anonymous
Ignoring @error -1 does not make TCPRecv mimic v3.3.8.1. It is still less effective than the genuine TCPRecv version 3.3.8.1. (Can't detect client side closed sockets is the nasty issue)
I've tested ignoreing -1 @errors and whatever errors are left can't detect closed client side sockets. This is very bad for servers that respond to web browser requests.
comment:11 Changed 11 years ago by Jpm
When I try to add the TCPConnect timeout I found that the @error set -1 for different case.
SO I modify the @error to identify uniquely the error.
In your case I main error come frome the fact that TCPConnect return timeout When the error occurs
You can find an updated version of Autoit3.exe at
http://www.autoitscript.com/autoit3/devs/jpm/#2384_UDPTCP_@error/
The .txt describe the change in @error
Just play with and report any comments
Thanks for your cooperation
Jpm
comment:12 Changed 11 years ago by anonymous
If I understand what I'm reading then this code should work to detect client side closed sockets but my tests say that the beta still can't detect client side closed sockets.
Downloaded the beta .exe from the link and updated my old exe.
Problem returns just as I remember it. Sorry... I can't think of any other solutions but to revert back to the older version.
This is what i'm using.
$tcprecvmessg = TCPRecv($recvsockets,$tcpmaxbitss,1) If @error < -1 Or @error > 0 Then ; Still can't detect client side closed sockets
Thank you for your time.
comment:13 Changed 11 years ago by Jpm
If you use the repro script I uploaded does the error occured on the TCPConnect() not on the TCPRecv()?
comment:14 Changed 11 years ago by FixTCPRecvForNewVersions
Not exactly sure what i'm suppose to do with that. But this is what I did. Installed the beta version you have there, then ran the repro script and this is what it came out with.
getting info -> @error = -3 @extended = 3
comment:15 Changed 11 years ago by Jpm
Sorry, I forget to upload your repro script a liitle bit modified
#2596 TCPRecv @error.au3
try with this new upload and you will see I think the TCPConnect() error
comment:16 Changed 11 years ago by FixTCPRecvForNewVersions
First time running the script get @error 10060 then counts @error -1 forever. All attempts after that show no errors. Only errors right after I switch .exe files from older to newer.
Looks like this script is emulating a browser request. You probably already know this but just for the sake of clarity, this problem is most dominant when the script acts like a server and is trying to satisfy the client browser's request. When the request is satisfied the client normally closes the socket. This is where @error -1 was super handy in older versions of TCPRecv, allowing the server to acknowledge the closed socket on it's own end.
Newer versions of TCPRecv seem to be vastly compromised because of the new @error levels.
Also TCPStartup() never ever shuts down unless the server is deactivated (in my script). It looked like the repo script was constantly starting and stopping. (Don't know if that matters)
comment:17 Changed 11 years ago by Jpm
The repro script was the one posted in the forum, no change in the logic.
THe intend version does not intend to change any of previous except implemenation of the TCPConnect timeout.
I am not a specialist of this net function. so please an update of the last post repro script so I can understand what should help. Perhaps you need 2 script one for the server and the other for the client.
Thanks for your cooperation
comment:18 follow-up: ↓ 20 Changed 11 years ago by diegomainster@…
Hello, I created this ticket, once I started ignoring @error = -1, my server is running fine, I'm using version 3.3.10.2, created these 2 scripts to demonstrate how do I detect when the client or server closes the connection, it works for me:
Server: http://pastebin.com/JPf3A8KE
Client: http://pastebin.com/irVGLpde
comment:19 Changed 11 years ago by Jpm
Many thanks,
Now I understand better (I think ?)
If the connection is closed by the other side you received in 3.3.8.1 -1
now with my TCPConnect implementation you received 10054 which means connection reset by peer which is better as the @error less than 0 can set in other situation
I Think you can agree that my TCPConnect() timeout solution is working fine as 3.3.8.1
Cheers
Jpm
comment:20 in reply to: ↑ 18 Changed 11 years ago by anonymous
Replying to diegomainster@…:
Hello, I created this ticket, once I started ignoring @error = -1, my server is running fine, I'm using version 3.3.10.2, created these 2 scripts to demonstrate how do I detect when the client or server closes the connection, it works for me:
Server: http://pastebin.com/JPf3A8KE
Client: http://pastebin.com/irVGLpde
Thank you for the examples. I'm glad that is working for you.
This does not work for what i'm doing. The only difference I can tell here is that i'm not using a Autoit3 client side version to connect to the server. (Don't know why that matters.) Same problem, Autoit3 server can't tell when client web browser closes the socket where older versions could.
I'm trying to get an example script working that will show case exactly what is happening between version 3.3.8.1 and the newer version 3.3.10.2 that will hopefully not make things even more confusing.
This is what i have learned so far.
Autoit3 v3.3.8.1 installed by using the setup download. Works as expected...
Autoit3 v3.3.10.2 installed by using the setup download. @error -1 is different, and causes problems when detecting a web browser closed socket. > 0 @error does not help here for whatever reason. Installing the beta version.exe did not seem to help.
HOWEVER.
When using the beta version on 3.3.8.1 there does not seem to be the problem that genuine 3.3.10.2 installs seem to have.(This was very confusing to me when making the trouble shooting script because I was assuming that it would not work.)
So unless you know a better way then I would recommend using the setup installers for switching between autoit3 versions. Uninstall-reinstall between 3.3.8.1 and 3.3.10.2 and then run the bellow repro script.
HOWEVER!
This too cause me problems! But I do not want to get into detail about it other than to warn you that when I was installing between versions that version 3.3.8.1 was acting out of character and I had to download a fresh copy of the 3.3.8.1 to correct it.
(Was getting extra TCP connections to the server that sent no data but would eventually close)
Before I was just swapping out exe files between beta and 3.3.8.1 when making this script, but the problem does not seem to start until you install the genuine 3.3.10.2 and then try swapping out with the beta version.
comment:21 Changed 11 years ago by anonymous
Sorry it is not working fine, I have tested all day and it is still not as good as old versions...
comment:22 Changed 11 years ago by anonymous
Would you like to see my repro script?
comment:23 Changed 11 years ago by FixTCPRecvForNewVersions
Sorry I was afraid you were going to close the ticket before I could finsih...
Here is the reproduction script.
Well here it is, hope it helps.
Remember the only way to reproduce the error that I know of is two use un-install and re-install between 3.3.8.1 and 3.3.10.2
This also creates a junk file to quickly simulate outgoing requests.
Hope that is ok.
#include <File.au3> $fletemp = _TempFile(@WorkingDir & "\","JUNK",".ini") $listsck = "" $lstnhst = "127.0.0.1" $lstnprt = 81 $maxrecv = 1000 $maxpend = 10 $version = @AutoItVersion $warning = "Begin this test by pointing your web browser to the host address." & @CRLF & "Host ip: " & $lstnhst & ":" & $lstnprt & @CRLF & @CRLF If $version <> "3.3.8.1" Then $warning &= "TCPRecv might not detect client side closed sockets, try version 3.3.8.1 for a working example." MsgBox(0,"Autoit3 Version?",$warning & @CRLF & "You are using AutoIt3; " & $version) $srvrnme = "TESTING TCPRecv v" & $version $srvrmsg = $srvrnme If $version = "3.3.8.1" Then $srvrmsg &= " (Can easily detect client side closed sockets)" Else $srvrmsg &= " (May not detect client side closed sockets very easily if at all, try version 3.3.8.1)" EndIf TCPStartup() If @error Then MsgBox(0,$srvrnme,"TCPStartup ERROR: " & @error) quit() Else $srvrsck = TCPListen($lstnhst,$lstnprt,$maxpend) If @error Then MsgBox(0,$srvrnme,"TCPListen ERROR: " & @error) quit() Else MsgBox(0,$srvrnme,$srvrsck) EndIf EndIf $blankexample = False $loop = 0 While 1 $clntsck = TCPAccept($srvrsck) If @error Then MsgBox(0,$srvrnme,$srvrsck & " TCPAccept ERROR: " & @error) quit() ElseIf $clntsck <> -1 Then $listsck &= $clntsck & "_" EndIf $split = StringSplit($listsck,"_") For $x = 1 To $split[0] If $split[$x] <> "" Then $clntsck = $split[$x] $clntmsg = TCPRecv($clntsck,$maxrecv) $ierror = @error If $ierror Then If $version <> "3.3.8.1" Then MsgBox(0,$srvrnme,"Socket: " & $clntsck & " Client message??? (" & $clntmsg & ")" & @CRLF & @CRLF & "Error??? " & $ierror) If $blankexample = True Then TCPCloseSocket($clntsck) IniDelete($fletemp,"SOCKETRQST",$split[$x]) $split[$x] = "" EndIf Else MsgBox(0,$srvrnme,"Socket: " & $clntsck & " TCPRecv has detected the client side closed socket and will now close the local socket. @error " & $ierror & @CRLF & @CRLF & $clntmsg) If $blankexample = True Then TCPCloseSocket($clntsck) IniDelete($fletemp,"SOCKETRQST",$split[$x]) $split[$x] = "" EndIf EndIf ElseIf $clntmsg <> "" Then IniWrite($fletemp,"SOCKETRQST",$clntsck,"Fake Message") Else $test = "set error for blank returns!? BBADD!" If $version = "3.3.8.1" Then $test = "error not set! GOOD!" MsgBox(0,$srvrnme,$blankexample & " Blank return detected, " & $ierror & @CRLF & @CRLF & $test & @CRLF & @CRLF & $clntsck) $blankexample = True EndIf EndIf Next If $listsck <> "" Then $listsck = "" For $x = 1 To $split[0] If $split[$x] <> "" Then $clntsck = $split[$x] $listsck &= $clntsck & "_" $clntmsg = IniRead($fletemp,"SOCKETRQST",$clntsck,"") If $clntmsg <> "" And $blankexample = True Then respond() EndIf Next EndIf Sleep(100) $loop += 1 If $loop >= 500 Then quit() WEnd Func respond() $size = StringLen($srvrmsg) $header = "HTTP/1.0 200 OK" & @CRLF $header &= "Content-Length: " & $size & @CRLF $srvrsnd = $header & @CRLF & $srvrmsg If $blankexample = True Then TCPSend($clntsck,$srvrsnd) ; Stop respond to better show the error example. If @error Then MsgBox(0,$srvrnme,"TCPSend: " & @error) quit() Else MsgBox(0,$srvrnme,"Client reqested: " & @CRLF & @CRLF & $clntmsg & @CRLF & @CRLF & "Message was sent to client: " & $clntsck & @CRLF & @CRLF & $srvrsnd) If $version <> "3.3.8.1" Then $theproblem = "This version must force close the connection here since @error -1 no longer behaves as expected. But going to leave it open for example." & @CRLF $theproblem &= "Force closing connections can have harmless but un-desirable effects for the client." & @CRLF $theproblem &= "@error -1 will be set for blank returns, which compramises the ability to detect client side closed sockets." MsgBox(0,$srvrnme,$theproblem) EndIf EndIf EndFunc Func quit() TCPShutdown() FileDelete($fletemp) Exit EndFunc
comment:24 Changed 11 years ago by FixTCPRecvForNewVersions
Sorry for junking things up, just wanted to let it be known that the extra TCP connections were obviously something my browser was doing and was able to fix it by turning off a setting. (Just never seen that before and was confusing me)... That issue has nothing to do with autoit3 and i'm sorry for bringing that up.
If you need more insight on the @error for new versions then i'd have to make a video of exactly what i'm experiencing over here to show you, if the new repro script does not help at all.
Thanks for your time.
comment:25 Changed 11 years ago by FixTCPRecvForNewVersionsPLEASE
Ran tests on a different operating system and it confirmed that TCPRcv still can not detect a client side closed web browser socket as older versions did. I tried the @error > 0 solution and still was unable to detect the client side closed web browser socket via @error 10054. Socket stays open forever even when the browser is closed.
Something is off there and it is killing autoit3's ability to function efficiently as a web server. Even worse try mixing the two together as a script that can do web serving and accept persistent autoit3 client connections. Can be done but 3.3.8.1. will out speed any newer version scripts at the same time be more reliable.
If you wish to continue thinking there is nothing wrong with TCPRecv then fine i'm ok with that. Future autoit3 users should be aware that scripting a web server with the newer versions wont be as effective. 3.3.8.1 will dominate over newer scripts with speed and rely ability. You might as well retire any thought of having a descent web servers using autoit3 for here on out if the issue is not resolved.
Good luck.
comment:26 Changed 11 years ago by diegomainster@…
I created a video to demonstrate it on my web server when the browser closes the connection, the connection is closed, don't "stays open forever":
comment:27 Changed 11 years ago by anonymous
I've done everything I know of to try and make your solution work without any success at all. I've tested it on three different operating systems and still nothing. I'm very confused at this point why @error > 0 will work for you when I can't even get a received message most of the time using that. Guess i'm SOL. If you have any last suggestions or ideas on what I need to fix in the reproduction script then please share them. I don't want to be stuck on 3.3.8.1 forever and am very curious as to what i'm doing differently that it will work for you and not me.
I've tried everything I can think of and am ready to concede the subject and just live with what I've got.
Thanks.
comment:28 Changed 11 years ago by anonymous
Sorry miss spoke again. I can receive the message, just can't detect the @error > 0 in order to close the socket.
Sorry for wasting your time.
comment:29 Changed 11 years ago by anonymous
Sorry miss spoke again. I can receive the message, just can't detect the @error > 0 in order to close the socket.
Sorry for wasting your time.
comment:30 Changed 11 years ago by anonymous
Sorry but this is driving me NUTS!
I'm sorry for spamming your forum.
If there is no TCPRecv error then why the holy molly is it so hard to work with now?
Why in gods name is this not working????
When diegomainster example server/client scripts can detect the error without a problem?
I concede that it is probably my scripting but what the heck happened that made TCPRecv so hard to deal with now?!? What in the world am I doing wrong? If you can explain this to me that would be great, in the meantime i'll search for a new place to research this.
When I run this script and open a web browser and goto the address and then close the browser the script does not detect @error > 0 !!!
Please explain to me if TCPRecv is not bugged, what in the WORLD am I doing wrong here?
TCPStartup() $serversock = TCPListen('127.0.0.1',81) While 1 Do $hi = TCPAccept($serversock) Until $hi <> -1 MsgBox(0,"Connected","A client has connected...") While 1 TCPRecv($hi,1500) If @error > 0 Then MsgBox(0,"Closed","Closing the connection: " & @error) TCPCloseSocket($hi) ExitLoop EndIf WEnd WEnd
comment:31 follow-up: ↓ 32 Changed 11 years ago by diegomainster@…
Now I understand the problem you described, and me using your code also happened in version 3.3.8.1. I realized that if you call TCPSend() sometimes, TCPRecv() detects the closing of the connection, as in the code below:
TCPStartup() $serversock = TCPListen('127.0.0.1', 81) While 1 Do $hi = TCPAccept($serversock) Until $hi <> -1 MsgBox(0,"Connected","A client has connected...") $ti = TimerInit() While 1 TCPRecv($hi,1500) If @error > 0 Then MsgBox(0,"Closed","Closing the connection: " & @error) TCPCloseSocket($hi) ExitLoop EndIf If TimerDiff($ti) > 99 Then TCPSend($hi, 'data') $ti = TimerInit() EndIf WEnd WEnd
So, there is even a problem with TCP in autoit.
comment:32 in reply to: ↑ 31 Changed 11 years ago by anonymous
Replying to diegomainster@…:
Now I understand the problem you described, and me using your code also happened in version 3.3.8.1.
I also tested the scripts with both versions. And 3.3.8.1 did not reflect the same problems as newer versions. I will assume that when you ran your scripts that @error was still set to > 0. (Easy miscalculation to do and would not hold it against a master coder like you or anyone else to oversee, I have done it countless times) But I realize assumptions are often misleading and am willing to diagnose why my version of 3.3.8.1 worked when @errror level is set properly for the version that is installed, when yours did not.
3.3.8.1 requires @error of any kind in order to close the socket.(Wow that is easy!)
Later versions seem to require an error > 0... Or oven perhaps less than -1...
definitely not an @error of -1 whatever you do. (@error -1 is worthless, and same as blank, why do we need two?)
Later version also seem to require some kind of delay witch TCPRecv never ever ever needed before. TimerInit seems to be the main root of why my scripts fail and your scripts succeed.(Best guess so far)
Bottom line:
Version 3.3.8.1 - When I tested did not require a TCPsend nor TimirInit delay, in oder to close the socket.
Later versions - Seem to require TimirInit before a response/closing. (Which is confusing but i'm ok with as long as there is proper documentation on how to implement the function because Autoit3 is great and should be available to use for everyone, not just elites. And that is what they have done to the best of their ability so far, and I'd hate to say that TCPRecv is not user friendly when it is possibly the most common used function of all time)
Once again I appreciate your patients in dealing with a guy like me who is a newbie to forums and coding, Autoit3 has been good to me for a long time and it upsets me that something I have been using for years no longer works the way I expected.
Now come on lets be honest please, which would you prefer... 3.3.8.1 needs no further action other than @error -1 to close a socket...
Later versions require a time delay, plus you got to ignore @error -1 because it is...??? uhh... Blank i guess, same as the return value? -1 = "" ok.... @error > 0 close socket... Oh plus developers got to make new example scripts to help newbies to learn. (Not that hard, but wow, 3.3.8.1 TCPRecv was so much more user friendlier)
You tell me which is not going to confuse the heck out of somebody who is learning TCPRecv.
3.3.8.1 @error -1 CLOSE THE SOCKET (DONE)
3.3.10.2 @error > 0 CLOSE THE SOCKET (OOOPS you forgot the time delay! TRY AGAIN!!!)
Not trying to be disrespectful just trying to make a point.
Sorry for the offence if any.
My overall goal is to help Autoit3 be the best it can be, and they probably are doing a great job without me, but the TCPRecv is my lively hood and means a lot to me. I have no problem staying with 3.3.8.1 for the rest of my days if that is all I can get to work for TCPRecv heavy scripts.
Thank you for your time.
I still love Autoit3, and they still deserve all the donations they can and will get.
comment:33 Changed 11 years ago by anonymous
In 3.3.8.1 it is even simpler than i describe it.. All you need is an @error of any kind to close the client side socket.
Newer versions require you to ignore @error -1 plus do a timer init delay before sending data. (If I understand correctly)
comment:34 Changed 11 years ago by anonymous
For the sake of clarity, this is a working example of 3.3.8.1 with proper @error detection set for the installation of genuine Autoit3 v3.3.8.1 and modified to remove server response to lesson the confusion.
When executed with 3.3.8.1 the script will close the socket as expected.
When executed with any other script greater than this version problems may arise!
Newer version require the comments to be removed, and @error detection be > 0...
And I believe without any further testing that this is the root difference between diegomainster's working examples and my failing examples.(Not tested elsewhere except the recent reproduction scripts).
Thank you all for helping me understand the new TCPRecv function.
Still don't care to add TimerInit, i'll stay with 3.3.8.1 for TCP related scripts until it is more user friendly(if ever).
Please update the example 'help' scripts for TCPRecv to reflect these changes if you had not already, or aren't planing to do so. (They are amazing and taught me everything I know, thank you for that)
TCPStartup()
$serversock = TCPListen('127.0.0.1', 81)
If @error Then Exit ; we know this one.
While 1TCPRecv
Do
$hi = TCPAccept($serversock)
If @error Then Exit ; we know this one.
Until $hi <> -1
MsgBox(0,"Connected","A client has connected...")
$ti = TimerInit()
While 1
TCPRecv($hi,1500)
If @error Then
MsgBox(0,"Closed","Closing the connection: " & @error)
TCPCloseSocket($hi)
ExitLoop
EndIf
#cs
If TimerDiff($ti) > 99 Then
TCPSend($hi, 'data')
If @error Then MsgBox(0,"SEND ERROR!",@error)
$ti = TimerInit()
EndIf
#ce
WEnd
WEnd
comment:35 Changed 11 years ago by anonymous
Whoops sorry, that one before this one got messed up somehow... This one should do better.
TCPStartup() $serversock = TCPListen('127.0.0.1', 81) If @error Then Exit ; we know this one. While 1 Do $hi = TCPAccept($serversock) If @error Then Exit ; we know this one. Until $hi <> -1 MsgBox(0,"Connected","A client has connected...") $ti = TimerInit() While 1 TCPRecv($hi,1500) If @error Then MsgBox(0,"Closed","Closing the connection: " & @error) TCPCloseSocket($hi) ExitLoop EndIf #cs If TimerDiff($ti) > 99 Then TCPSend($hi, 'data') If @error Then MsgBox(0,"SEND ERROR!",@error) $ti = TimerInit() EndIf #ce WEnd WEnd
comment:36 Changed 11 years ago by Jpm
Can you switch the discussion to Forum as too may post for a track report.
For me the uploaded version for solving the TCPConnect timeout and clarification of @error is enough to have a good handling of peer disconnection as @error is set to 10054 which exactly what MSDN is describing
WSAECONNRESET = 10054
Connection reset by peer.
An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket). This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.
comment:37 Changed 11 years ago by anonymous
Too bad that don't work for connected WEB BROWSER clients. 3.3.10.2 STILL can't detect 10054 and MUST rely on other means to detect the error when a client connects to the server with a WEB BROWSER! Even then the error is 10053 (PROTOCOL ERROR) and not a TIMEOUT because the socket is long closed on client side before any kind of time out (On client side) can occur.
I say it again! 3.3.10.2 CAN NOT detect 10054 when a web browser like CHROME OR anything else connects to the server...
The last two above scripts are the PROOF of it...! (comment 30 31 should be enough to proof that 3.3.10.2 TCPRecv @error detection is BROKEN when detecting client side closed browser sockets where 3.3.8.1 had no problems what soever!)
Thank you for your time.
comment:38 Changed 11 years ago by Jpm
I agrre that my TCPConnect timeout solution must be committed I will speak with Jon which is the only one which can commit for AutoIt change
comment:39 Changed 11 years ago by Autoit3 is Awesome!
Thank you for taking the time to investigate the matter. I appreciate the Autoit3 team's hard work and you guys/gals are doing an amazing job!
Thanks again.
comment:40 follow-up: ↓ 41 Changed 11 years ago by Lbsl
I stumbled upon the same problem.
Also evaded it by ignoring errors < 0.
But somehow this still does not solve the performance issue with tcprecv.
It seems to me that the Tcprecv is not clearing its buffers when it transferred the data content to my own receive buffer variable.
I have been running a simple client and server app that is parsing an enormous log-file from one side to the other.
It seems to choke faster the smaller the receive buffer size i set.
If i set it to receive 10.000 characters, the flow streams efficiently a lot longer yet eventually chokes as well (making the flow stutter), but if i set the receive buffer to 1K, it seems to choke much faster.
Whatever AutoIT 3.3.8.1 did on the TCPRecv and Send functions, worked much more efficiently than it currently does in the 3.3.10.2
Cheers.
comment:41 in reply to: ↑ 40 Changed 11 years ago by Lbsl
Replying to Lbsl:
Whatever AutoIT 3.3.8.1 did on the TCPRecv and Send functions, worked much more efficiently than it currently does in the 3.3.10.2
I overread the TCPTimeout comments above:
I figured out that the TCPTimeout (which is set to 500msecs in my case) is executed also on the errors below 0. I don't think this is really necessary as these errors are certain not to resolve the stuff that the -x errors produce, without developer intervention.
For sure the timeout should not be applied when the TCPRecv error is -1.
comment:42 Changed 10 years ago by anonymous
the answer to all questions
http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
comment:43 Changed 10 years ago by anonymous
That don't answer anything about how jacked up the new TCPREcv is...
comment:44 Changed 10 years ago by Jon
- Milestone set to 3.3.13.2
- Owner set to Jon
- Resolution set to Fixed
- Status changed from new to closed
Fixed by revision [10303] in version: 3.3.13.2
comment:45 Changed 10 years ago by TCPRecvFix
Tested a script with AutoIt version 3.3.13.16 beta and though TCP error detection has been improved it still can not detect client side closed sockets as 3.3.8.1 is able to do. The fixed version still requires a timeout to close the client side socket when dealing with a web browser. I love that empty returns do not set @error anymore, but it's still depressing that @error is not set for a client side web browser connection termination.
I don't know if this is a bug any more or a design change, so I wish to make a request as a big fan of AutoIt3 that you seriously consider 3.3.8.1's ability to detect client side web browser connection terminations and implement that in future versions.
I have created a script that can demonstrate this ability if your interested in pursuing this any further.
Thanks for taking the time to improve TCPRecv, and i'll do my best to adjust to the alternate methods for closing sockets.
comment:46 Changed 9 years ago by internetmonkeyboy@…
As of today still not setting @error level. Why is this still broken?
comment:47 Changed 9 years ago by internetmonkeyboy@…
Local $shost = "www.google.com"
Local $sPage = "/"
Local $iPort = 80
TCPStartup()
Local $sName_To_IP = TCPNameToIP($shost)
Local $iSocket = TCPConnect($sName_To_IP, $iPort)
If $iSocket = -1 Then
TCPCloseSocket($iSocket)
MsgBox(0, "Socket Connect Error", $iSocket, 0)
Exit
Else
MsgBox(0, "Socket Connected", $iSocket, 1)
EndIf
Local $sCommand = "GET " & $sPage & " HTTP/1.1" & @CRLF
$sCommand &= "Host: " & $shost & @CRLF
$sCommand &= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0" & @CRLF
$sCommand &= "Referer: " & $shost & @CRLF
$sCommand &= "Connection: close" & @CRLF & @CRLF
Local $BytesSent = TCPSend($iSocket, $sCommand)
If $BytesSent = 0 Then
MsgBox(0, "Sending Error", $BytesSent, 0)
Exit
EndIf
Local $sRecv = ""
Local $sCurrentRecv ;= ""
While 1
$sCurrentRecv = TCPRecv($iSocket, 1000)
If @error <> 0 Then ExitLoop
MsgBox(0, @error, $sCurrentRecv, 1)
WEnd
TCPCloseSocket($iSocket)
TCPShutdown()
comment:48 Changed 6 years ago by TJF
The problem still exists in v 3.3.14.5
TCPRecv doesn't return a correct @error message! If TCP-Server is testwise closed, the lost connection could not be detected by TCPRecv!
comment:49 Changed 4 years ago by Jpm
- Resolution Fixed deleted
- Status changed from closed to reopened
comment:50 Changed 4 years ago by Jpm
- Owner changed from Jon to Jpm
- Status changed from reopened to assigned
comment:51 Changed 4 years ago by TicketCleanup
- Milestone 3.3.13.2 deleted
Automatic ticket cleanup.
comment:52 Changed 4 years ago by Jpm
- Resolution set to Works For Me
- Status changed from assigned to closed
Hi I think the problem is closed just try the TCPSend/ TCPRecv second example using a big file
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
I ran it in a loop counting the number of time it succeeded and failed, and it failed 10 times with that error in 1000 tests. (test code: http://pastie.org/8595004 output: http://pastie.org/8595005)