JScript Posted June 24, 2014 Author Share Posted June 24, 2014 Thanks buddy, I'll do the tests and then return!JS http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!) Somewhere Out ThereJames Ingram Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere! Link to comment Share on other sites More sharing options...
jpm Posted June 24, 2014 Share Posted June 24, 2014 Okay, here's another stab and is up for review. I made it as an include this time, so you can test it in your scripts without doing too many modifications and to test the error returns. Just #include this script and replace TCPRecv with _WSA_TCPRecv and you're good to go. I downloaded a 1.2GB file with it today and it was also tested for server disconnects with no problems. Please review the code to find out what to expect from this script. jpm, I think I figured out what the problem is with disconnect -2. There's a mention of it in the script below. There are 3 possible returns from "recv". 1. blank = no bytes received. 2. 0 = disconnected. 3. greater than 0 = bytes received._WSA_TCPRecv.au3 Thanks goes to ProgAndy and JScript -- I borrowed some of their code. The non-blocking code by ProgAndy, was obtained from here:'?do=embed' frameborder='0' data-embedContent>> I don't understand how an int can be blank Link to comment Share on other sites More sharing options...
ripdad Posted June 24, 2014 Share Posted June 24, 2014 jpm, That IS exactly how it is. I've learned over the years to never take MSDN as absolute. Especially when they name example usage as LEAN AND MEAN. It's like pulling teeth to get a peek at the light for all the darkness. mLipok 1 "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward Link to comment Share on other sites More sharing options...
jpm Posted June 25, 2014 Share Posted June 25, 2014 jpm, That IS exactly how it is. I've learned over the years to never take MSDN as absolute. Especially when they name example usage as LEAN AND MEAN. It's like pulling teeth to get a peek at the light for all the darkness. whoah ... I will check again the proposed AutoIt code with what you suggest Stay tune THanks Link to comment Share on other sites More sharing options...
jpm Posted June 25, 2014 Share Posted June 25, 2014 In fact the Non_blocking socket is used only in the TCPConnect(). So I don't really know If i will not introduce a lot of regression applying it to TCPRecv() too Link to comment Share on other sites More sharing options...
ripdad Posted June 25, 2014 Share Posted June 25, 2014 In the code that ProgAndy used in _TCPConnect(), a non-blocking socket is used to set a timeout for a connection, and then set to blocking again once the connection is established. I'm not really sure what the proper protocols are between the two. I can't seem to find any documentation that suggest how they should be used, or even under what circumstances. TCPConnect() may use non-blocking to connect, but it seems that a dll call using "recv" is in blocking mode under normal conditions. At least that was my experience when I first tested it. Since I'm not privy to that code in AutoIt, I can only guess. But when I use a dll call using "recv" from TCPConnect(), it is in blocking mode, until a non-blocking call is issued. With that said, I can use ProgAndy's _TCPConnect(), and comment the blocking call towards the end of the script, and the dll "recv" call is non-blocking, and works accordingly. You don't have to change anything with that in regards to the AutoIt code anyways. The main reason for this last script was to show what the "recv" returns were, so that it might be helpful with the disconnect -2 problem. So, if you were to implement those returns, somewhat like the script suggest, then I think that problem will be fixed. "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward Link to comment Share on other sites More sharing options...
jpm Posted June 25, 2014 Share Posted June 25, 2014 My upload test of AutoIT3.exe is using the exact @progandy code, so my concern is to understand if such use of non-blocking socket can be used in other place at least in TCPRecv as you suggest without bringing some regression. JScript 1 Link to comment Share on other sites More sharing options...
JScript Posted June 25, 2014 Author Share Posted June 25, 2014 @jpm And about TCPSend() ? JS http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!) Somewhere Out ThereJames Ingram Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere! Link to comment Share on other sites More sharing options...
ripdad Posted June 25, 2014 Share Posted June 25, 2014 My upload test of AutoIT3.exe is using the exact @progandy code, so my concern is to understand if such use of non-blocking socket can be used in other place at least in TCPRecv as you suggest without bringing some regression. Well now, that presents a puzzle. How is TCPRecv in non-blocking mode? If TCPRecv was in blocking mode, then it would "wait" indefinitely for incoming data, unless some type of timeout was issued, like 10ms. Which, I don't think you can issue a timeout while in blocking mode. Hence, the ProgAndy code. Perhaps there is more code in one of the libraries that deals with it. In any case, the answer to your question is, I didn't experience any noticeable difference or problems while using it. If you adapt ProgAndy's _TCPConnect(), then you might have no choice but to use the script I posted at #40. Because that is exactly what I wound up having to do. I had no choice, if I wanted it to work properly. --- As a side matter, I worked with a blocking function that I named: _WSA_TCPRecvWait(). The idea was to wait for 3 seconds and if no data received then return. I couldn't get it to work in that mode. Somehow TCPRecv is in non-blocking mode when called. If not in your code, then in one of the includes. Or perhaps it is called differently than in the script. I don't know - I'm in the dark at this point, again. "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward Link to comment Share on other sites More sharing options...
funkey Posted June 25, 2014 Share Posted June 25, 2014 As a side matter, I worked with a blocking function that I named: _WSA_TCPRecvWait(). The idea was to wait for 3 seconds and if no data received then return. I couldn't get it to work in that mode. You have to use a non-blocking socket and the function select() to do this. Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
JScript Posted June 25, 2014 Author Share Posted June 25, 2014 @funkeyI figured that way, then that means that all the socket should have a single mode of operation?I find most interesting is the TCPSend it were in non-blocking modeJS http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!) Somewhere Out ThereJames Ingram Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere! Link to comment Share on other sites More sharing options...
ripdad Posted June 25, 2014 Share Posted June 25, 2014 (edited) You have to use a non-blocking socket and the function select() to do this. Thanks, but I'm aware of that. Did you review the script at post #40? By the way funkey, since you are familiar with WSA sockets, you should be giving your points of view. It's good to hear from you anytime! Do you have any knowledge on blocking and non-blocking protocols? When they should or should not be used? What are the pros and cons? What are the security concerns? I'm looking for documentation. I think I have an idea to run them more efficiently. Edited June 25, 2014 by ripdad "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward Link to comment Share on other sites More sharing options...
ripdad Posted June 25, 2014 Share Posted June 25, 2014 (edited) @funkey I figured that way, then that means that all the socket should have a single mode of operation? I find most interesting is the TCPSend it were in non-blocking mode JS I think TCPSend can be set in non-blocking mode, but I'm not sure at this point, what effects it will have. I will have to play with it sometime within the next week. Let's get TCPRecv working properly first. -edit- silly editor Edited June 25, 2014 by ripdad "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward Link to comment Share on other sites More sharing options...
ripdad Posted June 27, 2014 Share Posted June 27, 2014 (edited) Please review - final stab - I hope. Included is: _TCPConnect() - a rewrite of the original code. _WSA_TCPRecv() - removed the blocking calls and modified a few lines. _TPCRecv_Example() - example usage for a function. - edit- code deleted to avoid confusion. Edited June 29, 2014 by ripdad "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward Link to comment Share on other sites More sharing options...
funkey Posted June 27, 2014 Share Posted June 27, 2014 Here are my tcp functions and examples: http://www.autoit.de/index.php?page=Attachment&attachmentID=24567&h=ca64bd1c55936912df877c3045756d05bda42374 Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
JScript Posted June 27, 2014 Author Share Posted June 27, 2014 Thank you both, I'll do the tests!JS http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!) Somewhere Out ThereJames Ingram Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere! Link to comment Share on other sites More sharing options...
jpm Posted June 27, 2014 Share Posted June 27, 2014 Before I start to update the standard TCP functions, can I have a description of difference between the 2 approaches? Thanks for the help Link to comment Share on other sites More sharing options...
funkey Posted June 27, 2014 Share Posted June 27, 2014 (edited) I always test if there is data availabe with select(). I don't understand the documentation because of the maxlen parameter. It it the buffer size for recv or is it to cut of the result? Here is what I made but I did not enough testing: expandcollapse popup#include "socket_UDF.au3" Global $sIP = "www.google.com" Global $iPort = 80 Global $ConnectionTimeout = 1500 Global $tReadFds = DllStructCreate($tagFd_set) Global $tReadFds_Copy = DllStructCreate($tagFd_set) _WSAStartup() Global $iSocket = _TCPConnect($sIP, $iPort, $ConnectionTimeout) If @error Then ConsoleWrite("_TCPConnect() error " & @error & " / (" & @extended & ") connecting to " & $sIP & ":" & $iPort & @LF) _WSACleanup() Exit EndIf ConsoleWrite("Connection established to " & $sIP & ":" & $iPort & @LF) ConsoleWrite("New socket: " & $iSocket & @LF & @LF) TCPSend($iSocket, "GET /index.html HTTP/1.0" & @CRLF & @CRLF) Global $sHTML = _TCPRecv($iSocket) If @error Then ConsoleWrite("_TCPRecv() error " & @error & " / (" & @extended & ") for socket " & $iSocket & @LF & @LF) EndIf _closesocket($iSocket) _WSACleanup() ConsoleWrite($sHTML & @LF) Func _TCPRecv($iSocket, $iBufLen = 2048, $iTimeout = 2000) Local $iRetSelect, $iRetRecv;, $sRet = "", $sTemp = "" Local $tReadFds = DllStructCreate($tagFd_set) Local $tReadFds_Copy = DllStructCreate($tagFd_set) Local $tBuffer = DllStructCreate("char buffer[" & $iBufLen & "]") _FD_ZERO($tReadFds) _FD_SET($iSocket, $tReadFds) While 1 DllCall('ntdll.dll', 'none', 'RtlMoveMemory', 'struct*', $tReadFds_Copy, 'struct*', $tReadFds, 'ULONG_PTR', DllStructGetSize($tReadFds)) $iRetSelect = _select($tReadFds_Copy, $iTimeout) Switch $iRetSelect Case $SOCKET_ERROR Return SetError(1, _WSAGetLastError(), "") Case 0 ; Timeout (no or no more data) Return SetExtended(0, "") Case Else If _FD_ISSET($iSocket, $tReadFds_Copy) Then DllCall('ntdll.dll', 'none', 'RtlZeroMemory', 'struct*', $tBuffer, 'ULONG_PTR', DllStructGetSize($tBuffer)) $iRetRecv = _recv($iSocket, $tBuffer) Switch $iRetRecv Case $SOCKET_ERROR Return SetError(2, _WSAGetLastError(), "") Case 0 ; Connection closed or no more data Return SetError(3, 0, "") Case Else Return SetExtended($iRetRecv, DllStructGetData($tBuffer, 1)) EndSwitch Else ExitLoop EndIf EndSwitch WEnd EndFunc ;==>_TCPRecv Edited November 11, 2014 by funkey Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
ripdad Posted June 27, 2014 Share Posted June 27, 2014 (edited) Just my opinion, but I think TCPConnect should be left in non-blocking mode in AutoIt. Blocking mode may have its applications - but this is not one of them. -edit- I changed my mind on the statement above when I found out the security concerns on non-blocking sockets. ------ And there is no point in switching between the two. So here is how it works, based on observation: 1. The default state of a socket is in blocking mode. It works just like "any blocking function". 2. The dll call to "ioctlsocket", last parameter "1", changes it to non-blocking mode. In my script, using _TCPConnect(), it is left in non-blocking mode, until the socket is closed. 3. The behavior of non-blocking mode works as it should. MS added a 10035 non-fatal error while in that mode. It is basically saying, that the non-blocking socket has no data queued (or it's blank), so try again! That behavior, is what we expect from TCPRecv. 4. There is no noticeable difference when using TCPSend at this point. It works like it always has. 5. There are two new features, if added to AutoIt: - TCPConnect would have a timeout option/parameter. For instance 3 seconds, instead of the default 20 seconds, which that has never been acceptable. - TCPRecv would return "bytes received" in @extended. This will save coders from all those StringLen() calls. It's in the dll call, might as well put it to good use! @extended returns: 0 = no bytes received. >0 = number of bytes received. --- Hmm, I can't think of anything else right now. I have things to do - maybe later. Edited June 29, 2014 by ripdad "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward Link to comment Share on other sites More sharing options...
ripdad Posted June 27, 2014 Share Posted June 27, 2014 I always test if there is data availabe with select(). Could you post the dll call using "select" to test availability?DllCall(...) I don't understand the documentation because of the maxlen parameter. It it the buffer size for recv or is it to cut of the result? It's the buffer size. (the number of bytes to receive) When you set the buffer size, "recv" will fill data up to that size. Hence, maxlen. "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward Link to comment Share on other sites More sharing options...
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