Sign in to follow this  
Followers 0
Fr0zT

TCPRecv Not completing

4 posts in this topic

#1 ·  Posted (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 by Fr0zT

[size="1"][font="Lucida Console"]My ScriptsTrue multi-threaded ping[/font][/size]

Share this post


Link to post
Share on other sites



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

Share this post


Link to post
Share on other sites

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

#4 ·  Posted (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 by Fr0zT

[size="1"][font="Lucida Console"]My ScriptsTrue multi-threaded ping[/font][/size]

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0