Что нового

Прием файла по TCP

andriy111

Новичок
Сообщения
58
Репутация
0
Доброй ночи!
Уважаемые форумчане помогите с задачей!
После отправки ниже показаного пост запроса, сервер отвечает файлом. Но я видимо что-то неправильно делаю и не могу принять и сохранить этот файл...=(
Прошу Вашей помощи! Спасибо!

Код:
$sParametersDownload='OriginURL=%2Fshop%2Forder.php&OrderID='&$sOrderID&'&Download=Download';
$Download = 'POST /shop/redirect.php HTTP/1.1' & @CRLF
$Download &= 'Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*'& @CRLF ;Заголовки
$Download &= 'Referer: http://server.com/shop/order.php?OrderID='&$sOrderID&'' & @CRLF ;Заголовки
$Download &= 'Accept-Language: ru-RU' & @CRLF
$Download &= 'User-Agent: Demianovych Bot' & @CRLF
$Download &= 'Content-Type: application/x-www-form-urlencoded' & @CRLF
$Download &= 'Accept-Encoding: gzip, deflate' & @CRLF
$Download &= 'Host: server.com' & @CRLF
$Download &= 'Content-Length: ' & StringLen($sParametersDownload) & @CRLF ;Указываем заголовок Content-Length (необходимо для POST-запроса)
$Download &= 'Connection: Keep-Alive' & @CRLF
$Download &= 'Cache-Control: no-cache' & @CRLF
$Download &= 'Cookie: CoordinateSystem=geographical; DeliveryType=download; EMailType=single; NotifyMail=0; RINEXType=1; Lang=ENG; '&$cookie_mid&'' & @CRLF
$Download &= @CRLF ;Заголовки от параметров отделяет пустая строка
$Download &= $sParametersDownload ;Параметры в запросе;;

If TCPStartup() = 0 Then ;запускаем TCP/UDP-службы
    MsgBox(16, 'Ошибка', 'Не удалось запустить TCP/UDP-службы.')
   Exit 1
EndIf

$sIP = TCPNameToIP($sDomain) ;получаем ip-адрес

If @error Then
  MsgBox(16, 'Ошибка', 'Не удалось получить ip-адрес сервера.')
  Exit 2
EndIf

$iSocket = TCPConnect($sIP, $iPort) ;соединяемся с сервером

If @error Then
   MsgBox(16, 'Ошибка', 'Не удалось соедениться с сервером.')
Exit 3
EndIf

TCPSend($iSocket, $Download) ;отправляем сообщение

If @error Then
    MsgBox(16, 'Ошибка', 'Не удалось отправить запрос.')
    Exit 4
EndIf

$sFile = ''
$iTimer = TimerInit() ;запускаем таймер

Do
    $sBuffer = TCPRecv($iSocket, 1024)
    $iError = @error
    If Not $sBuffer = '' Then 
       $sFile &= $sBuffer
       $iTimer = TimerInit() ;обнуляем таймер
    EndIf
Until $iError <> 0 Or TimerDiff($iTimer) > 5000 ;если при получении сообщения произошла ошибка (данные получены, соединение закрыто) или в течении 5 секунд ничего не было получено, выход из цикла

TCPCloseSocket($iSocket)
TCPShutdown()

FileWrite("C:/1.zip",$aFile[1])
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Вот тебе найденый у буржуинов пример получения файла через TCP*:
Код:
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>


;Create a GUI with a progress indicator for download status
; #### Unfinished ####
Opt("GUIOnEventMode", 1)

$Form1 = GUICreate("Multi Segment downloader", 294, 56, 192, 124)
$Progress1 = GUICtrlCreateProgress(8, 8, 275, 20)
$Label1 = GUICtrlCreateLabel("Chunksize (MB):", 8, 32)
$edit = GUICtrlCreateInput("2",90,32,50,20)
$Updown1 = GUICtrlCreateUpdown($edit)
GUISetState(@SW_SHOW)



TCPStartup()

$sFile = @ScriptDir & '\file.avi' ; File to wrtie the download data to

$download= "http://speedtest.qsc.de/500MB.qsc" ; Internetfile to download

$refer = $download ; $refer = complete http path

$download = StringReplace($download,"http://","",1)

$string = StringSplit($download, "/",2)

;$string[0] = speedtest.qsc.de ; needed for 'Host:' in http referr

$PFileURL = ""
For $i = 1 To UBound($string)-1
    $PFileURL &= "/"&$string[$i]
next

;$PFileURL = /folder/misc/500MB.qsc ; needed for file path in http referr

TCPStartup()


$ip = TCPNameToIP($string[0])

ConsoleWrite($string[0]&" -> IP: "&$ip & @CRLF)


$size = 10000000 ; preset the size to 10MB, just in case we have an problem getting it from http responses

;~ $size = InetGetSize("http://"&$download) ; <-- some servers dont allow this

ConsoleWrite("Size of file: "&$size&" bytes"& @CRLF)


dim $chunkarr[4][7] ; [4] = maximum nr of simultanious chunks
;[0] = socket
;[1] = chunkstart
;[2] = chunkend
;[3] = chunksize
;[4] = data
;[5] = downloding
;[6] found the 0d0a0d0a after header?
ConsoleWrite(@CRLF& @CRLF & @CRLF)

$chunksize = GUICtrlRead($edit)*1024*1024 ; initial size of each segment

ConsoleWrite("Chunksize: "&$chunksize&" bytes"& @CRLF)

$nextchunkPos = 0 ; Starting at Byte

FileDelete ( $sFile)

$hFile = _WinAPI_CreateFile($sFile, 3,4,2)

While 1
    $chunksize = GUICtrlRead($edit)*1024*1024
    Sleep(50)
    $chunksactive = 0
    For $i = 0 To UBound($chunkarr)-1 ; go through each chunk
        if $chunkarr[$i][5] = 0 and $nextchunkPos < $size then ; Unused ChunkSlot --> Request new chunk

            $chunkarr[$i][1] = $nextchunkPos    ; start
            $chunkarr[$i][2] = $nextchunkPos+$chunksize-1   ; end

            $chunkarr[$i][4] = Binary("")       ; data
            $chunkarr[$i][5] = 1        ; downloading
            $chunkarr[$i][6] = 0        ; found the 0d0a0d0a after header

            if $chunkarr[$i][2]+$chunksize >= $size then $chunkarr[$i][2] = $size-1; if last chunk set end to last byte

            $chunkarr[$i][3] = $chunkarr[$i][2]-$chunkarr[$i][1]+1  ; size

            RequestChunk($i)

            $nextchunkPos = $chunkarr[$i][2]+1

        endif

        if $chunkarr[$i][5] = 1 then ; current chunk is marked downloading
            $chunksactive += 1
            RecvChunk($i)
        endif



    next
    if $chunksactive = 0 then ExitLoop
WEnd

ConsoleWrite( @CRLF&" #####    DOWNLOAD FINISHED    #####" & @CRLF)
_WinAPI_CloseHandle($hFile)

Exit


func RequestChunk($chunknr)

    ; Prepare Header
    $h  = "GET "&$PFileURL&" HTTP/1.1" & @CRLF
    $h &= "Referer: "&$refer & @CRLF
    $h &= "Range: bytes=" & $chunkarr[$chunknr][1] & "-" & $chunkarr[$chunknr][2] & @CRLF ; <----  ### important part for multi segment downloading ###
    $h &= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.8) Gecko/20100722 Ant.com Toolbar 2.0.1 Firefox/3.6.8" & @CRLF
    $h &= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" & @CRLF
    $h &= "Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3" & @CRLF
    $h &= "Accept-Encoding: gzip,deflate" & @CRLF
    $h &= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" & @CRLF
    $h &= "Keep-Alive: 115" & @CRLF
    $h &= "Connection: keep-alive" & @CRLF
    $h &= "Host: " & $string[0] & @CRLF
    $h &= "Pragma: no-cache" & @CRLF
    $h &= @CRLF

;~  ConsoleWrite("+############### HEADER ################"& @CRLF)
;~  ConsoleWrite($h & @CRLF)

;~  ConsoleWrite("+-------------------- HEADER END ------------------"& @CRLF)

    $chunkarr[$chunknr][0] = TCPConnect($ip, 80)
    $err=@error
    $bs = TCPSend( $chunkarr[$chunknr][0], $h)
    ConsoleWrite( "-Chunk "&$chunknr&" request: Range: bytes= " & $chunkarr[$chunknr][1] & "-" & $chunkarr[$chunknr][2] &" / "&$chunkarr[$i][3]&" ("&$bs&" bytes sent)"&@CRLF)

    If  $chunkarr[$chunknr][0] = -1 Or $err Then
        ConsoleWrite("  TCPConnect error" & @CRLF)
        Exit
    EndIf

endfunc


func RecvChunk($chunknr)

    $data = TCPRecv( $chunkarr[$chunknr][0], 800,1)

    If @error <> 0 Then ; this chunk closed its connection
        ConsoleWrite(@CRLF&"Closed Connection (Chunk "&$chunknr&" finished)" & @CRLF)

        if BinaryLen($chunkarr[$chunknr][4]) < $chunkarr[$chunknr][3] then ; downloaded bytes are not equal requested size
            $cs = TCPCloseSocket ( $chunkarr[$chunknr][0] )
            ConsoleWrite("!Chunk mismatch: "&$chunknr&" finished ("&$cs&") with "&BinaryLen($chunkarr[$chunknr][4])&" bytes ("&floor(($nextchunkPos/$size)*100)&"%)"&@CRLF)

            ConsoleWrite(BinaryToString($chunkarr[$chunknr][4]) & @CRLF)
            ConsoleWrite("!resetting chunk("&$chunknr&") data and request again... " & @CRLF)
            $chunkarr[$chunknr][4] = Binary("")     ; reset data

            RequestChunk($chunknr)

        else; Chunk finished
            $chunkarr[$chunknr][5] = 0
            $tBuffer = DLLStructCreate("byte[" & BinaryLen ($chunkarr[$chunknr][4]) & "]")

            DLLStructSetData($tBuffer, 1, $chunkarr[$chunknr][4])
            local $nBytes

            $fp = _WinAPI_SetFilePointer($hFile, $chunkarr[$chunknr][1])
    ;~      ConsoleWrite("File Pointer to "&$chunkarr[$chunknr][1]&" --> Result: "&$fp & @CRLF)

            $wf = _WinAPI_WriteFile($hFile,DLLStructGetPtr($tBuffer), $chunkarr[$i][3], $nBytes)
    ;~      ConsoleWrite("Write File "&$chunkarr[$i][3]&" bytes: "&$wf & @CRLF)

            $tBuffer = 0
            ;~ ConsoleWrite('3) ' & FileRead($sFile) & @LF)
            $cs = TCPCloseSocket ( $chunkarr[$chunknr][0] )
            ConsoleWrite("+Chunk "&$chunknr&" finished ("&$cs&") with "&BinaryLen($chunkarr[$chunknr][4])&" bytes ("&floor(($nextchunkPos/$size)*100)&"%)"&@CRLF)

        endif
        return 0
    endif

    ; This chunk is still receiving data..
    if not ($data = "") then
        $timer = TimerInit()
        do
            if $chunkarr[$chunknr][6] = 0 then ; if we didnt found the 0d0a0d0a position yet
                $data2 = binary("")
                For $i = 0 To BinaryLen($data)
                    ; search the first bytes of the incoming packet for the 0d0a0d0a string
                    ; $data2 will be used as fill up variable and usually contains the whole header
                    ; cant use stringinstr or Regex functions since any 0x00 character in the file will mess both up seriously!
                    $bit = BinaryMid($data,$i,1)
                    $data2 &= $bit

                    if StringRight($data2,8) = binary("0D0A0D0A") then ; found header, stored in $data2
                        $marr = StringRegExp(BinaryToString($data2),"Content-Range: bytes \d+-\d+/(\d+)",3) ; get exact size of file from header

                        $size = $marr[0]

                        $data2 = binary("")
                        $chunkarr[$chunknr][6] = 1 ; found the 0d0a0d0a position
                        ConsoleWrite("Content Range Size: [" &$marr[0]&"], 0D0A0D0A pos: ["&$i&"]"&@CRLF)
                    endif
                Next
                $data = $data2; reset $data, from now on the file starts
            endif

            $chunkarr[$chunknr][4] &= $data ; save the data of this chunk to global array
            $data = TCPRecv( $chunkarr[$chunknr][0], 4048,1)

        until $data == "" or TimerDiff($timer)  > 10000 ; 10 second timeout

    endif

    return 1
endfunc
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Код:
$sParametersDownload='OriginURL=%2Fshop%2Forder.php&OrderID='&$sOrderID&'&Download=Download';
$Download = 'POST /shop/redirect.php HTTP/1.1' & @CRLF
$Download &= 'Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*'& @CRLF ;Заголовки
$Download &= 'Referer: http://server.com/shop/order.php?OrderID='&$sOrderID&'' & @CRLF ;Заголовки
$Download &= 'Accept-Language: ru-RU' & @CRLF
$Download &= 'User-Agent: Demianovych Bot' & @CRLF
$Download &= 'Content-Type: application/x-www-form-urlencoded' & @CRLF
$Download &= 'Accept-Encoding: gzip, deflate' & @CRLF
$Download &= 'Host: server.com' & @CRLF
$Download &= 'Content-Length: ' & StringLen($sParametersDownload) & @CRLF ;Указываем заголовок Content-Length (необходимо для POST-запроса)
$Download &= 'Connection: Keep-Alive' & @CRLF
$Download &= 'Cache-Control: no-cache' & @CRLF
$Download &= 'Cookie: CoordinateSystem=geographical; DeliveryType=download; EMailType=single; NotifyMail=0; RINEXType=1; Lang=ENG; '&$cookie_mid&'' & @CRLF
$Download &= @CRLF ;Заголовки от параметров отделяет пустая строка
$Download &= $sParametersDownload ;Параметры в запросе;;

If TCPStartup() = 0 Then ;запускаем TCP/UDP-службы
    MsgBox(16, 'Ошибка', 'Не удалось запустить TCP/UDP-службы.')
   Exit 1
EndIf

$sIP = TCPNameToIP($sDomain) ;получаем ip-адрес

If @error Then
  MsgBox(16, 'Ошибка', 'Не удалось получить ip-адрес сервера.')
  Exit 2
EndIf

$iSocket = TCPConnect($sIP, $iPort) ;соединяемся с сервером

If @error Then
   MsgBox(16, 'Ошибка', 'Не удалось соедениться с сервером.')
Exit 3
EndIf

TCPSend($iSocket, $Download) ;отправляем сообщение

If @error Then
    MsgBox(16, 'Ошибка', 'Не удалось отправить запрос.')
    Exit 4
EndIf

$iTimer = TimerInit() ;запускаем таймер

Do
    $sBuffer = TCPRecv($iSocket, 1024)
    If @error Then
		ExitLoop
	EndIf
    If $sBuffer <> '' Then
	   FileWrite("1.zip", $sBuffer)
       $iTimer = TimerInit() ;обнуляем таймер
    EndIf
Until $sBuffer == '' Or TimerDiff($iTimer) > 5000 ;если при получении сообщения произошла ошибка (данные получены, соединение закрыто) или в течении 5 секунд ничего не было получено, выход из цикла

TCPCloseSocket($iSocket)
TCPShutdown()
 
Автор
A

andriy111

Новичок
Сообщения
58
Репутация
0
сасибо Всем!
sngr Ваш скрипт почему-то у меня работает цыклично не останавливаясь и постоянно отдает в консоль данные Но если вручную прописать в переменную $size число с Content-Length: , то все отлично скачивается! Не могу домудрить реализацию такой замены числа. Помогите новичку=)
Код:
Closed Connection (Chunk 0 finished)
!Chunk mismatch: 0 finished (True) with 47026 bytes (214%)
HTTP/1.1 200 OK
Date: Sat, 18 May 2013 08:01:35 GMT
Server: Apache/2.2.4 (Win32)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: cache
Content-Disposition: attachment; filename="Order288.zip"
Content-Length: 46662
Connection: close
Content-Type: application/x-zip-compressed

PK!resetting chunk(0) data and request again... 
-Chunk 0 request: Range: bytes= 0-99999 / 100000 (783 bytes sent)

Мой модификация кода выглядит так, не исключено что я что-то делаю не так...
Код:
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>


;Create a GUI with a progress indicator for download status
; #### Unfinished ####
Opt("GUIOnEventMode", 1)

$Form1 = GUICreate("Multi Segment downloader", 294, 56, 192, 124)
$Progress1 = GUICtrlCreateProgress(8, 8, 275, 20)
$Label1 = GUICtrlCreateLabel("Chunksize (MB):", 8, 32)
$edit = GUICtrlCreateInput("2",90,32,50,20)
$Updown1 = GUICtrlCreateUpdown($edit)
GUISetState(@SW_SHOW)

TCPStartup()

$sFile = @ScriptDir & '\'&$sOrderID&'.zip' ; File to wrtie the download data to

$download= "http://server.com/shop/redirect.php" ; Internetfile to download

$refer = $download ; $refer = complete http path

$download = StringReplace($download,"http://","",1)

$string = StringSplit($download, "/",2)

;$string[0] = speedtest.qsc.de ; needed for 'Host:' in http referr

$PFileURL = ""
For $i = 1 To UBound($string)-1
    $PFileURL &= "/"&$string[$i]
next

;$PFileURL = /folder/misc/500MB.qsc ; needed for file path in http referr

TCPStartup()


$ip = TCPNameToIP($string[0])

ConsoleWrite($string[0]&" -> IP: "&$ip & @CRLF)


$size = 100000 ; preset the size to 10MB, just in case we have an problem getting it from http responses

;~ $size = InetGetSize("http://"&$download) ; <-- some servers dont allow this

ConsoleWrite("Size of file: "&$size&" bytes"& @CRLF)


dim $chunkarr[4][7] ; [4] = maximum nr of simultanious chunks
;[0] = socket
;[1] = chunkstart
;[2] = chunkend
;[3] = chunksize
;[4] = data
;[5] = downloding
;[6] found the 0d0a0d0a after header?
ConsoleWrite(@CRLF& @CRLF & @CRLF)

$chunksize = GUICtrlRead($edit)*1024*1024 ; initial size of each segment

ConsoleWrite("Chunksize: "&$chunksize&" bytes"& @CRLF)

$nextchunkPos = 0 ; Starting at Byte

FileDelete ( $sFile)

$hFile = _WinAPI_CreateFile($sFile, 3,4,2)

While 1
    $chunksize = GUICtrlRead($edit)*1024*1024
    Sleep(50)
    $chunksactive = 0
    For $i = 0 To UBound($chunkarr)-1 ; go through each chunk
        if $chunkarr[$i][5] = 0 and $nextchunkPos < $size then ; Unused ChunkSlot --> Request new chunk

            $chunkarr[$i][1] = $nextchunkPos    ; start
            $chunkarr[$i][2] = $nextchunkPos+$chunksize-1   ; end

            $chunkarr[$i][4] = Binary("")       ; data
            $chunkarr[$i][5] = 1        ; downloading
            $chunkarr[$i][6] = 0        ; found the 0d0a0d0a after header

            if $chunkarr[$i][2]+$chunksize >= $size then $chunkarr[$i][2] = $size-1; if last chunk set end to last byte

            $chunkarr[$i][3] = $chunkarr[$i][2]-$chunkarr[$i][1]+1  ; size
			
            RequestChunk($i)
			
            $nextchunkPos = $chunkarr[$i][2]+1
			

        endif

        if $chunkarr[$i][5] = 1 then ; current chunk is marked downloading
            $chunksactive += 1
            RecvChunk($i)
			
        endif
	  


    next
    if $chunksactive = 0 then ExitLoop
WEnd

ConsoleWrite( @CRLF&" #####    DOWNLOAD FINISHED    #####" & @CRLF)
_WinAPI_CloseHandle($hFile)

Exit


func RequestChunk($chunknr)

    ; Prepare Header
	$sParametersDownload='OriginURL=%2Fshop%2Forder.php&OrderID='&$sOrderID&'&Download=Download';
    $h  = "POST "&$PFileURL&" HTTP/1.1" & @CRLF
    $h &= "Range: bytes=" & $chunkarr[$chunknr][1] & "-" & $chunkarr[$chunknr][2] & @CRLF ; <----  ### important part for multi segment downloading ###
    $h &= "Pragma: no-cache" & @CRLF
	$h &= 'Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*'& @CRLF ;Заголовки
$h &= 'Referer: http://server.com/shop/order.php?OrderID='&$sOrderID&'' & @CRLF ;Заголовки
$h &= 'Accept-Language: ru-RU' & @CRLF
$h &= 'User-Agent: Demianovych Bot' & @CRLF
$h &= 'Content-Type: application/x-www-form-urlencoded' & @CRLF
$h &= 'Accept-Encoding: gzip, deflate' & @CRLF
$h &= 'Host: server.com' & @CRLF
$h &= 'Content-Length: ' & StringLen($sParametersDownload) & @CRLF ;Указываем заголовок Content-Length (необходимо для POST-запроса)
$h &= 'Connection: Keep-Alive' & @CRLF
$h &= 'Cache-Control: no-cache' & @CRLF
$h &= 'Cookie: CoordinateSystem=geographical; DeliveryType=download; EMailType=single; NotifyMail=0; RINEXType=1; Lang=ENG; '&$cookie_mid&'' & @CRLF
$h &= @CRLF ;Заголовки от параметров отделяет пустая строка
$h &= $sParametersDownload ;Параметры в запросе;;
	
;~  ConsoleWrite("+############### HEADER ################"& @CRLF)
;~  ConsoleWrite($h & @CRLF)

;~  ConsoleWrite("+-------------------- HEADER END ------------------"& @CRLF)

    $chunkarr[$chunknr][0] = TCPConnect($ip, 80)
    $err=@error
    $bs = TCPSend( $chunkarr[$chunknr][0], $h)
    ConsoleWrite( "-Chunk "&$chunknr&" request: Range: bytes= " & $chunkarr[$chunknr][1] & "-" & $chunkarr[$chunknr][2] &" / "&$chunkarr[$i][3]&" ("&$bs&" bytes sent)"&@CRLF)

    If  $chunkarr[$chunknr][0] = -1 Or $err Then
        ConsoleWrite("  TCPConnect error" & @CRLF)
        Exit
    EndIf

endfunc


func RecvChunk($chunknr)

    $data = TCPRecv( $chunkarr[$chunknr][0], 800,1)

    If @error <> 0 Then ; this chunk closed its connection
        ConsoleWrite(@CRLF&"Closed Connection (Chunk "&$chunknr&" finished)" & @CRLF)

        if BinaryLen($chunkarr[$chunknr][4]) < $chunkarr[$chunknr][3] then ; downloaded bytes are not equal requested size
            $cs = TCPCloseSocket ( $chunkarr[$chunknr][0] )
            ConsoleWrite("!Chunk mismatch: "&$chunknr&" finished ("&$cs&") with "&BinaryLen($chunkarr[$chunknr][4])&" bytes ("&floor(($nextchunkPos/$size)*100)&"%)"&@CRLF)

            ConsoleWrite(BinaryToString($chunkarr[$chunknr][4]) & @CRLF)
            ConsoleWrite("!resetting chunk("&$chunknr&") data and request again... " & @CRLF)
            $chunkarr[$chunknr][4] = Binary("")     ; reset data

            RequestChunk($chunknr)

        else; Chunk finished
            $chunkarr[$chunknr][5] = 0
            $tBuffer = DLLStructCreate("byte[" & BinaryLen ($chunkarr[$chunknr][4]) & "]")

            DLLStructSetData($tBuffer, 1, $chunkarr[$chunknr][4])
            local $nBytes

            $fp = _WinAPI_SetFilePointer($hFile, $chunkarr[$chunknr][1])
    ;~      ConsoleWrite("File Pointer to "&$chunkarr[$chunknr][1]&" --> Result: "&$fp & @CRLF)

            $wf = _WinAPI_WriteFile($hFile,DLLStructGetPtr($tBuffer), $chunkarr[$i][3], $nBytes)
    ;~      ConsoleWrite("Write File "&$chunkarr[$i][3]&" bytes: "&$wf & @CRLF)

            $tBuffer = 0
            ;~ ConsoleWrite('3) ' & FileRead($sFile) & @LF)
            $cs = TCPCloseSocket ( $chunkarr[$chunknr][0] )
            ConsoleWrite("+Chunk "&$chunknr&" finished ("&$cs&") with "&BinaryLen($chunkarr[$chunknr][4])&" bytes ("&floor(($nextchunkPos/$size)*100)&"%)"&@CRLF)

        endif
        return 0
    endif

    ; This chunk is still receiving data..
    if not ($data = "") then
        $timer = TimerInit()
        do
            if $chunkarr[$chunknr][6] = 0 then ; if we didnt found the 0d0a0d0a position yet
                $data2 = binary("")
                For $i = 0 To BinaryLen($data)
                    ; search the first bytes of the incoming packet for the 0d0a0d0a string
                    ; $data2 will be used as fill up variable and usually contains the whole header
                    ; cant use stringinstr or Regex functions since any 0x00 character in the file will mess both up seriously!
                    $bit = BinaryMid($data,$i,1)
                    $data2 &= $bit

                    if StringRight($data2,8) = binary("0D0A0D0A") then ; found header, stored in $data2
                        ;$marr = StringRegExp(BinaryToString($data2),"Content-Length: (.*?)",3) ; get exact size of file from header
						$marr = StringRegExp(BinaryToString($data2), '(?:Content-Length: )([0-9]{1,})(?:)', 1) 
                        $size = $marr[0]

                        $data2 = binary("")
                        $chunkarr[$chunknr][6] = 1 ; found the 0d0a0d0a position
                        ConsoleWrite("Content Range Size: [" &$marr[0]&"], 0D0A0D0A pos: ["&$i&"]"&@CRLF)
                    endif
                Next
                $data = $data2; reset $data, from now on the file starts
            endif

            $chunkarr[$chunknr][4] &= $data ; save the data of this chunk to global array
            $data = TCPRecv( $chunkarr[$chunknr][0], 4048,1)

        until $data == "" or TimerDiff($timer)  > 10000 ; 10 second timeout

    endif
   
    return 1
	if $marr[0]<>0 then $nextchunkPos=$marr[0]
endfunc




Ваша модификация Viktor1703 к сожалению, в моем случае, не записывает ничего...=(
 
Автор
A

andriy111

Новичок
Сообщения
58
Репутация
0
UP
Кто-то может помочь с присваиванием значения перменной $size числа с
Код:
$marr = StringRegExp(BinaryToString($data2), '(?:Content-Length: )([0-9]{1,})(?:)', 1)
?? Спасибо!
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Код:
#include <WinAPI.au3>


$sFile = @ScriptDir & '\'&$sOrderID&'.zip' ; File to wrtie the download data to

$download= "http://server.com/shop/redirect.php" ; Internetfile to download

$refer = $download ; $refer = complete http path

$download = StringReplace($download,"http://","",1)

$string = StringSplit($download, "/",2)

;$string[0] = speedtest.qsc.de ; needed for 'Host:' in http referr

$PFileURL = ""
For $i = 1 To UBound($string)-1
    $PFileURL &= "/"&$string[$i]
next

;$PFileURL = /folder/misc/500MB.qsc ; needed for file path in http referr

TCPStartup()


$ip = TCPNameToIP($string[0])


ConsoleWrite($string[0]&" -> IP: "&$ip & @CRLF)

;=====================================================
;получаешь размер либо так  

$size = InetGetSize("http://"&$download) ; <-- some servers dont allow this

;либо этак

$sParametersDownload='OriginURL=%2Fshop%2Forder.php&OrderID='&$sOrderID&'&Download=Download';
$h  = "POST "&$PFileURL&" HTTP/1.1" & @CRLF   
$h &= "Pragma: no-cache" & @CRLF
$h &= 'Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*'& @CRLF ;Заголовки
$h &= 'Referer: http://server.com/shop/order.php?OrderID='&$sOrderID&'' & @CRLF ;Заголовки
$h &= 'Accept-Language: ru-RU' & @CRLF
$h &= 'User-Agent: Demianovych Bot' & @CRLF
$h &= 'Content-Type: application/x-www-form-urlencoded' & @CRLF
$h &= 'Accept-Encoding: gzip, deflate' & @CRLF
$h &= 'Host: server.com' & @CRLF
$h &= 'Content-Length: ' & StringLen($sParametersDownload) & @CRLF ;Указываем заголовок Content-Length (необходимо для POST-запроса)
$h &= 'Connection: Keep-Alive' & @CRLF
$h &= 'Cache-Control: no-cache' & @CRLF
$h &= 'Cookie: CoordinateSystem=geographical; DeliveryType=download; EMailType=single; NotifyMail=0; RINEXType=1; Lang=ENG; '&$cookie_mid&'' & @CRLF
$h &= @CRLF ;Заголовки от параметров отделяет пустая строка
$h &= $sParametersDownload ;Параметры в запросе;;

$iSocket = TCPConnect($sIP, $iPort) ;соединяемся с сервером

If @error Then
   MsgBox(16, 'Ошибка', 'Не удалось соедениться с сервером.')
Exit 3
EndIf

TCPSend($iSocket, $h) ;отправляем сообщение

If @error Then
    MsgBox(16, 'Ошибка', 'Не удалось отправить запрос.')
    Exit 4
EndIf

$sFile = ''
$iTimer = TimerInit() ;запускаем таймер

Do
    $sBuffer = TCPRecv($iSocket, 1024)
    $iError = @error
    If Not $sBuffer = '' Then 
       $sFile &= $sBuffer
       $iTimer = TimerInit() ;обнуляем таймер
    EndIf
Until $iError <> 0 Or TimerDiff($iTimer) > 5000 

$size=StringRegExpReplace($sFile,'(?s).*?Content-Length:\s+(\d+).*','\1')

;=============================================

;~ $size = 100000 ; preset the size to 10MB, just in case we have an problem getting it from http responses



ConsoleWrite("Size of file: "&$size&" bytes"& @CRLF)


dim $chunkarr[4][7] ; [4] = maximum nr of simultanious chunks
;[0] = socket
;[1] = chunkstart
;[2] = chunkend
;[3] = chunksize
;[4] = data
;[5] = downloding
;[6] found the 0d0a0d0a after header?
ConsoleWrite(@CRLF& @CRLF & @CRLF)

$chunksize = 1*1024*1024 ; initial size of each segment

; и т д
 
Автор
A

andriy111

Новичок
Сообщения
58
Репутация
0
Код:
$size = InetGetSize("http://"&$download) ; <-- some servers dont allow thi

возврасчает постоянно 612 байт=(

Воторой способ6
$size возврасчает значение :
Код:
x485454502F312E3120323030204F4B0D0A446174653A2053756E2C2031 и так далее 93000 байт информации=(

=(( Почему так? Как выйти с этого?
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Пробуй
Код:
$size=StringRegExpReplace(binarytostring($sFile),'(?s).*?Content-Length:\s+(\d+).*','\1')
 
Автор
A

andriy111

Новичок
Сообщения
58
Репутация
0
Уже пробовал...без результата=(


Добавлено:
Сообщение автоматически объединено:

Пробовал использовать то что есть в скрипте.
Код:
$data2 = binary("")
For $i = 0 To BinaryLen($sFile)
                    ; search the first bytes of the incoming packet for the 0d0a0d0a string
                    ; $data2 will be used as fill up variable and usually contains the whole header
                    ; cant use stringinstr or Regex functions since any 0x00 character in the file will mess both up seriously!
                    $bit = BinaryMid($sFile,$i,1)
                    $data2 &= $bit

                    if StringRight($data2,8) = binary("0D0A0D0A") then ; found header, stored in $data2
                        ;$marr = StringRegExp(BinaryToString($data2),"(?s).*?Content-Length:\s+(\d+).*",3) ; get exact size of file from header
						$marr = StringRegExp(BinaryToString($data2), '(?:Content-Length: )([0-9]{1,})(?:)', 1) 
                        $size = $marr[0]

                        $data2 = binary("")
                        $chunkarr[$chunknr][6] = 1 ; found the 0d0a0d0a position
                        ConsoleWrite("=========Content Range Size: [" &$marr[0]&"], 0D0A0D0A pos: ["&$i&"]"&@CRLF)
                    endif
                Next

Но почему-то зависает и не дает никакого результата при том что 0D0A0D0A существует в том бинарном ответе....


Добавлено:
Сообщение автоматически объединено:

0D0A0D0A - это фраза которой заканчиваются заголовки.
Не понятно почему скрипт зависает, хотя должен давать логичный ответ....
не срабатывает BinaryToString =(


Добавлено:
Сообщение автоматически объединено:

Не останавливается (не проходит проверку) на фразе 0D0A0D0A....в строке
Код:
if StringRight($data2,8) = binary("0D0A0D0A") then

...помогите найти ошибку...=(


Добавлено:
Сообщение автоматически объединено:

В итоге выяснилось что проблема в двойном переводе данных в бинарный вид строке
Код:
$marr = StringRegExp(BinaryToString(BinaryToString($data2)), '(?:Content-Length: )([0-9]{1,})(?:)', 1)
 
Верх