Jump to content
Sign in to follow this  
Biatu

[WIP] TCPRecv Downloader with AutoSpeed

Recommended Posts

Biatu

WIP, but this is what i have so far...

Concept: TCP allows only a set amount of data to be received on each use of its function.
I thought it would be better to dynamically change the amount of data received in a loop.

1. If the amount of data received is equal to the amount requested, increase request size.
2. If amount is lower than requested, then lower request size.

3. Add a multiplier to increase the amount by which the request size is increased or decreased. (For fast rate matching)
4. After the request size is roughly matched, lower multiplier in order to increase precision.
5. If time taken to download requested size is above a certain threshold, lower requested size.


The output is as follows:

Multiplier | TCPRecv Size | Total Bytes Recieved | TCPRecv Bytes | TCPRecv TImer

#include <Array.au3>
#include <WinAPIex.au3>
$RecvTime = 0
$GetRecvSize = 0
$RecvdSize = 0
$RecvSize = 2
$RecvMultiplier = 0
$TestTImer = TImerInit()
MsgBox(64, "", BinaryToString(Get("cachefly.cachefly.net","/100mb.test")))


Func Get($Domain, $Path)
Global $GetResponse
$GetBuffer = ""
$GetTimeout = 30000
TCPSTartup() ; Startup TCP

;Resolve IP from Domain Name
ConsoleWrite("Resolving "&$Domain&"...")
$GetIP = TCPNameToIP($Domain)
If @Error Then
    Return SetError(@Error,@ScriptLineNumber,@Error)
EndIf
ConsoleWrite("OK!"&@CRLF)

;Connect to Server
ConsoleWrite("Connecting to "&$Domain&"...")
$GetSocket = TCPConnect($GetIP, 80)
If @Error Then
    Return SetError(@Error,@ScriptLineNumber,@Error)
EndIf
ConsoleWrite("OK!"&@CRLF)

;Send URI Request
ConsoleWrite("Sending Request...")
$GetRequest = TCPSend($GetSocket,'GET '&$Path&' HTTP/1.1'&@CRLF&'User-Agent: AutoIt TCPGet Componet'&@CRLF&'Host: '&$Domain&@CRLF&'Cache-Control: no-cache'&@CRLF&@CRLF)
If @Error Then
    Return SetError(@Error,@ScriptLineNumber,@Error)
EndIf
ConsoleWrite("OK!"&@CRLF)

;Wait for Response
ConsoleWrite("Waiting for response...")
$TimeoutTimer = TimerInit()
Do
$GetResponse &= BinarytoString(TCPRecv($GetSocket,1,1))
ConsoleWrite(".")
If @Error AND TImerDiff($TimeoutTimer) >= $GetTimeout Then
    Return SetError(@Error,@ScriptLineNumber,@Error)
EndIf
Until StringInStr($GetResponse,@CRLF&@CRLF)
$GetResponse = StringSplit($GetResponse, @CRLF,1)

; Convert Header to Array.
For $a = $GetResponse[0] to 1 Step -1
    If ($GetResponse[$a] = "" OR $GetResponse[$a] = @LF OR $GetResponse[$a] = @CRLF OR $GetResponse[$a] = @CR) Then
        _ArrayDelete($GetResponse, $a)
        $GetResponse[0] -= 1
    EndIf
Next

; Check for Content-Length Header.
For $a = 0 to $GetResponse[0]
    If StringInStr($GetResponse[$a],"Content-Length: ") Then
        $GetSize = StringTrimLeft($GetResponse[$a], 16)
        ExitLoop
    EndIf
Next
ConsoleWrite("OK!"&@CRLF)

; Recieve Data...
ConsoleWrite("Recieving...")
$RecvTime = 0
Do
$RecvTimer = TimerInit()
$GetRecieve = TCPRecv($GetSocket,$RecvSize,1)
$GetRecvSize = BinaryLen($GetRecieve)
$RecvTime = TimerDiff($RecvTimer)
If @Error AND TimerDiff($TimeoutTimer) >= $GetTimeout Then
    SetError(@Error,@ScriptLineNumber)
    ExitLoop
EndIf
        If $RecvTime >  0.6 Then
            $RecvMultiplier = $RecvMultiplier - 1
            If $RecvMultiplier <= 0 Then $RecvMultiplier = 2
        EndIf
        If $RecvTime <  0.4 Then
            $RecvMultiplier = $RecvMultiplier + 1
            If $RecvMultiplier >= 1048576 Then $RecvMultiplier = 1048576
        EndIf

        If $GetRecvSize > $RecvSize Then ; $RecvTime >  0.4 OR
            $RecvSize = $RecvSize -  2 * $RecvMultiplier
            If $RecvSize <= 0 Then $RecvSize = 2 * $RecvMultiplier
        EndIf
        If $GetRecvSize = $RecvSize Then ;$RecvTime <  0.08 OR
            $RecvSize = $RecvSize +  2 * $RecvMultiplier
            If $RecvSize >= 1073740000 Then $RecvSize = 1073741824
        EndIf

If StringLen($GetRecieve) > 0 then
    $GetBuffer &= $GetRecieve
    $RecvdSize = BinaryLen($GetBuffer)
    If BInaryLen($GetBuffer) >= 100663296 Then
        ;Purge Data
        ;FileWrite("Tesmp.dat",$GetBuffer)
        ;$GetBuffer = ""
        ExitLoop ; 96MB Max
    EndIf
    If IsDeclared("GetSize") AND (BInaryLen($GetBuffer) = $GetSize) Then
        ;FileWrite("Tesmp.dat",$GetBuffer)
        ;$GetBuffer = ""
        ExitLoop ; File is Complete
    EndIf
EndIf
Sleep(10)
    ConsoleWrite(StringFormat("%03d",$RecvMultiplier)&"|"&StringFormat("%010d",$RecvSize)&"|"&StringFormat("%010d",$RecvdSize)&"|"&StringForUntil False
; Cleanup and Return Data
TCPCloseSocket($GetSocket)
TCPShutdown()
$GetRecieve = ""
$GetResponse = ""
$GetRequest = ""
$GetSocket = ""
$GetIP = ""
_WinAPI_EmptyWorkingSet()
Return $GetBuffer
EndFunc
Edited by Biatu

What is what? What is what.

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  

×