Fr0zT 2 Posted April 13, 2010 (edited) Hi All, I'm hoping someone can help me with TCPRecv. I am using it quite successfully in my program for all but one HTTP POST call. All of the message does not arrive, it gets cut off. I have used wireshark to confirm that the entire message came in, but doesn't show up in $recv. I should have received 2960 bytes but I actually got about 1060 (after HTTP header.) It's also strange becuase normally when I POST with TCPSend, the [Next sequence number] of TCP properties end up being the [ACK] number when it comes back with "HTTP/1.1 200 OK", but with this one post, the [Next sequence number] was 696 and the [ACK] that came back was 697. Also right before the [ACK] was a [RST,ACK] which I assume has something to do with it being out of order (I don't see these resets anywhere else.) I have tried this from 2 different locations so I know it's not a firewall issue, besides I can see all of the data in wireshark, it just doesn't get to autoit TCPRecv. Also I know the problem is limited to Autoit because it works fine natively in a custom browser app. Here is a basic snip of my code: AutoItSetOption("TCPTimeout", "1000") ;I have tried higher values here too and with/without quotes.... TCPStartup() Local $dst="some IP address", $recv = "", $ConnectedSocket = TCPConnect($dst, 80), $postPacket="Some HTTP request here" TCPSend($ConnectedSocket, $postPacket) If @error Then _checkSocketErrors() ;just checks if socket <> -1 otherwise closes it While $recv = "" $recv = TCPRecv($ConnectedSocket, 131072) ;I have tried many values from 2048 and up.. ;I've also tried the BinaryToString with binary option for TCPRecv ;I have a GUIGetMsg() deal here for easing up on the tight loop. but I've tried it without WEnd consolewrite($recv & @CRLF) that's pretty much it. It works great on smaller bits of data, but over the 1024 area and I start missing stuff. Thanks in advance for any help! Edited April 13, 2010 by Fr0zT [size="1"][font="Lucida Console"]My ScriptsTrue multi-threaded ping[/font][/size] Share this post Link to post Share on other sites
BrettF 28 Posted April 14, 2010 Maybe try editing your receiving loop? ;Reset $recv $recv = "" ;Start a loop While 1 ;Recieve data $recv &= TCPRecv($ConnectedSocket, 1024) ;If error then we have recieved all data or something has gone wrong ;Exit the loop If @error Then ExitLoop WEnd ;Display recieved data. MsgBox (0, "", $recv) Cheers, Brett Vist my blog!UDFs: Opens The Default Mail Client | _LoginBox | Convert Reg to AU3 | BASS.au3 (BASS.dll) (Includes various BASS Libraries) | MultiLang.au3 (Multi-Language GUIs!)Example Scripts: Computer Info Telnet Server | "Secure" HTTP Server (Based on Manadar's Server)Software: AAMP- Advanced AutoIt Media Player | WorldCam | AYTU - Youtube Uploader Tutorials: Learning to Script with AutoIt V3Projects (Hardware + AutoIt): ArduinoUseful Links: AutoIt 1-2-3 | The AutoIt Downloads Section: | SciTE4AutoIt3 Full Version! Share this post Link to post Share on other sites
Fr0zT 2 Posted April 14, 2010 While 1 ;Recieve data $recv &= TCPRecv($ConnectedSocket, 1024) ;If error then we have recieved all data or something has gone wrong ;Exit the loop If @error Then ExitLoop WEnd I have been trying it that way as well with no luck (actually more like this is what I think you meant) While 1 ;Recieve data $recv &= TCPRecv($ConnectedSocket, 1024) ;If error then we have recieved all data or something has gone wrong ;Exit the loop If @error = 0 Then ExitLoop WEnd [size="1"][font="Lucida Console"]My ScriptsTrue multi-threaded ping[/font][/size] Share this post Link to post Share on other sites
Fr0zT 2 Posted April 16, 2010 (edited) Alright I've figured it out. Turns out it was a timing thing all along. I just needed to wait a little longer for the data to come in. But probing @error for a 0 or -1 just doesn't work well enough so I decided instead that since this is HTTP, I could parse out the Content-Length and just wait until I got it all(or time-out) Local $bytes = 0, $timer_start = TimerInit() While 1 _checkMessages() ;My nMsg routine $recv &= TCPRecv($ConnectedSocket, 4096) If @error = -1 Then ExitLoop ;Just to be thorough $parse_start = StringInStr($recv, "Content-Length") + 15 If $parse_start > 15 Then $bytes = Int(StringStripWS(StringStripCR(StringMid($recv, $parse_start, StringInStr($recv,@CRLF,0,1,$parse_start) - $parse_start)),8)) ;This is what really makes the difference. Were waiting for all the data to come in If $bytes > 0 And StringLen($recv) >= $bytes Then ExitLoop If TimerDiff($timer_start) > 1000 + ($seconds * 1000) Then $seconds += 1 GUICtrlSetData($g_go, $seconds) If $seconds = 5 Then ExitLoop ;Last resort EndIf WEnd That did the trick, now the TCPRecv routine waits until it has received all the data before exiting. Edited April 16, 2010 by Fr0zT [size="1"][font="Lucida Console"]My ScriptsTrue multi-threaded ping[/font][/size] Share this post Link to post Share on other sites