vkill'blog 何永鹏

ruby download progress 2

08:50 , vkill
bjsh给我写了个python的,我看了下原理,又去看看了socket编程,自己用ruby写了个雏形,还有未考虑到的,以后完善
用 socket ,比分片下载好很多


#!/usr/bin/env ruby
#
# ruby Download progress 2
# by:vkill     last change:28/6/2009
# Usage: *.rb http://xxx.net/xxx.xxx
#
require 'socket'
require 'uri'

RECV_DATA_LEN = 1024
have_read = 0
url = ($*[0]||"http://avira.vkill.net/upd/vdf/antivir3.vdf.gz")

u = URI.parse(url)
fileName = File.basename(u.path)

begin
  $s = TCPsocket.new(u.host,u.port)
rescue
  puts "create socket Err, #{$!}"
  exit
end

downing = Thread.new {
  header = {"User-Agent" => "antivir-ruby"}
  req = "GET "+url+" HTTP/1.0\r\n"
  header.each do |k,v|
    req += k+":"+v+"\r\n"
  end
  begin
    $s.write(req+"\r\n")
  rescue
    puts "download file Err, #{$!}"
    self.kill
  end
}

while downing.status == "run" or downing.status == "sleep" do
  #read header
  $s.recv(1024).each_line do |d|
    if $dataStart
      have_read += d.length
      $f.write(d)
      next
    end
    if (/^HTTP\//i =~ d) != nil
      $statu = d.split(" ")[1]
      if not /^(200)$/ =~ $statu
        puts "download file Err, statu #{$statu}"
        downing.kill
        exit
      end
      next
    end
    if (/^Content-Length:[\t ]*[\d]+[\r\n]*$/i =~ d) != nil
      $totalLength = d.gsub(/.*:[\t ]*/,"").to_i
      next
    end
    if (/^[\r\n]*$/ =~ d) != nil
      $dataStart = true
      $f = File.new(fileName, "wb+")
      next
    end
  end
  if not $dataStart
    puts "download file Err, parser httpHeader error"
    downing.kill
    exit
  end
  $totalLength ||= 1

  #read data
  while true
    printf "\rdowning #{fileName}...[#{$totalLength}bytes] #{(have_read*100) / $totalLength}%"
    begin
      resp = $s.recv(RECV_DATA_LEN)
    rescue
      puts "download file Err, #{$!}"
      downing.kill
      exit
    end
    if resp == ""
      printf "\rdowning #{fileName}...[#{$totalLength}bytes] 100%\n"
      break
    end
    have_read += resp.length
    $f.write(resp)
  end
end

$f.close()

case downing.status
  when false
    puts "downing normally quit"
  when nil
    puts "downing unnormally quit"
  else
    puts "downing nuknow quit"
end



bjsh写的python的

import socket

READ_ONCE_SIZE = 512
have_read = 0

fd = open("c:\\test.rar", "wb")

s = socket.socket()
s.connect(("blog.vkill.net", 80))
s.sendall("GET http://blog.vkill.net/attachment/1221875343_6600827a.rar HTTP/1.0\n\n")


content = s.recv(READ_ONCE_SIZE)

while True:
    start = 0;
    start = content.find('\n')
    if content[start+1] == '\n':
        content = content[start+2:]
        break;
    if content[start+1] == '\r' and content[start+2] == '\n':
        content = content[start+3:]
        break;
    if content.startswith("Content-Length"):
        totalLength = int(content[:start].split()[1])
    content = content[start+1:]
            
have_read += len(content)

fd.write(content)

while True:
    print "\rtest.rar.....%d\t\t%5d%%" % (totalLength, have_read*100/totalLength),
    content = s.recv(READ_ONCE_SIZE)
    if not content:
        print "\rtest.rar.....%d\t\t%5d%%\n" % (totalLength, 100),
        break
    fd.write(content)
    have_read += len(content)

fd.close()


Last modified by vkill on2009/08/07 16:58
类别:ruby & rails | Tags: , , , , | 0 条评论, 360 次阅读
网友评论(0):
发表评论:

Nickname: 
Email:
Site URI: