Chinaunix首页 | 论坛 | 博客
  • 博客访问: 604578
  • 博文数量: 69
  • 博客积分: 2204
  • 博客等级: 大尉
  • 技术积分: 808
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-11 22:37
个人简介

..微笑着看着杯中的花茶一片片撑开.. ..透明的花瓣里水破开的声音很轻微..

文章分类

全部博文(69)

文章存档

2018年(1)

2017年(2)

2016年(10)

2015年(8)

2014年(6)

2013年(6)

2012年(4)

2011年(8)

2010年(12)

2009年(12)

分类: Python/Ruby

2010-08-06 18:25:05

    一直想写一个自己的(多线程||多进程)的网络下载程序,就像网络蚂蚁那样的。一直以来有好多瓶颈无法突破。幸运的是从网络上看到一篇perl写的http的断点续传的文章。上面就说,“不知道有没有在写网络蚂蚁之类软件的人呢。”笑~看来我还是幸运的。好了,闲话少说。先贴代码,然后在做注释。希望自己能一步一步达到自己的预期目标。
 
代码如下:
 

#!perl!



#socket读取远程文件;



use strict;
use IO::Socket qw(:DEFAULT :crlf); #调用IO:Socket模块;

use Errno qw/EINTR/; #摘自大骆驼,用途还没搞懂;


my $blksize = 1024; #设定下载时分块的大小;

my ($host,$port,$path,$written,$buf,$offset);#一些变量;

my $address_new = shift; #命令行读入下载地址;

my $newfile = shift; #要保存的文件名。


#解析地址,提取域名,端口和uri;

($host,$port,$path) = ($1,$2||80,$3) if($address_new =~ m!^(?:http://)?(.*?)(?::([0-9]+))?(/.*)$!x);

print "[$host] [$port] [$path]\n\n";


#下面这段是采用new方法创建连接;

my $socket = IO::Socket::INET->new(

PeerAddr => $host,
PeerPort => $port,
Type => SOCK_STREAM,
Timeout => 20

) or die "Can't connect:$!";


#向下面是向服务器发送http请求;

print $socket "GET $path HTTP/1.1\n";
print $socket "HOST:$host\n";
print $socket "Connection: close\n\n";

open TO,">$newfile";
#使用sysread和syswrite来读入和保存文件。

while (my $len = sysread $socket, $buf, $blksize) {
   if (!defined $len) {
      next if $! == EINTR;
      die "System read error: $!\n"
   }
   $offset = 0;
   while ($len) {
      $written = syswrite TO, $buf, $len, $offset;
      die "System write error: $!\n" unless defined $written;
      $offset += $written;
      $len -= $written;
   }
}

close TO;
close $socket;


这么一个简单的脚本学到了很多东西。包括http的协议等,很多都是重新仔细看的。以前没有注意,用到的时候方恨知道的少了。

写这个脚本的时候主要遇到几个问题:

1.一开始老是只能读取html页面(返回200),却不能读出二进制文件(返回400)。找了半天毛病,最后才知道是http的请求构建的有问题。大概对面的服务器不知道我在干嘛。不仔细学习HTTP协议是不行的。

2.如何读取远程文件并写入本地文件。我想这个方法有很多了。但是为了下一步准备,我还是选择了sysread和syswrite的方法。因为我打算用syseek来重定位指针。这样希望可以实现分块下载的目的。而且有些读入和写文件的方法写完的文件是损坏的,不知道是什么问题。可能用法不对。现在这段是摘自大骆驼书上的函数说明里的用法。不知道有没有更简洁的写法。不过这么写确实没有问题。有很多细节还需要消化。还不是很明白。

好久没复习多线程了,下一步希望能通过多线程实现对大文件的分块下载。

要学的东西还很多啊。。。 O(∩_∩)O

by lanmeibanban

2010-08-06

 

最后附个源码吧~

文件: net_get.rar
大小: 0KB
下载: 下载

阅读(1901) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~