FTP多线程下载 求助(200分)

  • 主题发起人 主题发起人 nicchen
  • 开始时间 开始时间
N

nicchen

Unregistered / Unconfirmed
GUEST, unregistred user!
我用的是INDY的IDFTP 不过好像不支持多线程下载
那位好心人帮帮我~~
最好给点源码让我参考 主要是将一个文件拆分成N份 然后多个线程同时下载这个文件
 
可以??具体怎么做啊???
 
可以的应该,但是不知道具体咱做
 
我晕。。。。老大们 知道的帮下忙丫
 
一般ftp服务器是不只持多线程下载的,你死了这条心吧
 
我自己开的服务器端啊 可以多线程 我现在就是想知道客户端多线程的弄啊
 
话题980648的标题是: ftp的多线程下载问题!!(很急,各位兄弟帮帮忙,没有那么的分了,请谅解) (50分)
分类:局域网 / 通讯 pzh509 (2002-03-13 15:10:00)
整个程序是这样的:在主窗口中有一个button按钮,两个edit文本框
(用于输入ftp服务器里要下载的文件名),
当按下button按钮后,创建两个线程使它们同时下载(采用IDFTP组件)
线程的整个代码如下:
unit Unit2;

interface

uses
Classes,IdFTP,Dialogs,StdCtrls;

type
dlthread = class(TThread)
private
{ Private declarations }
myidftp:tidftp;
mysavedialog:tsavedialog;
myedit:tedit;
protected
procedure Execute; override;
procedure download;//下载
public
constructor create(idftp:tidftp;savedialog:tsavedialog;aedit:tedit);
end;

implementation

constructor dlthread.create(idftp:tidftp;savedialog:tsavedialog;aedit:tedit);
begin
inherited create(false);
myidftp:=idftp;
mysavedialog:=savedialog;
myedit:=aedit;
freeonterminate:=true;//线程运行结束后,使线程自动释放本身的资源
end;

procedure dlthread.download;
begin
if mysavedialog.Execute then
begin
myidftp.TransferType:=ftbinary;//下载模式
myidftp.Get(myedit.Text,mysavedialog.FileName,true);//开始下载,mysavedialog.FileName存放 //的是下载到客户端的文件名
end;
end;

procedure dlthread.Execute;
begin
{ Place thread code here }
synchronize(download);
if terminated then
exit;
end;

end.
主窗口的主要代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var:
threadrunning:integer;//标识正在运行的线程数目
mydownthread1:dlthread;
mydownthread2:dlthread;
begin
threadrunning:=2;
mydownthread1:=dlthread.create(idftp1,savedialog1,edit1);
mydownthread1.OnTerminate:=threaddone;
mydownthread2:=dlthread.create(idftp1,savedialog2,edit2);
mydownthread2.OnTerminate:=threaddone;
end;

procedure TForm1.threaddone(sender:tobject);
begin
dec(threadrunning);
end;
但为什么它们不会同时下载?(运行结果是:等到第一个下载完后再接着下载
另一个,而实际上synchronize()函数是可以使线程同步执行的啊!)该怎么解决??

还有一个问题是:采用IDftp组件怎样做到断点传输??


win32api (2002-04-09 0:42:00)
可以这样,在线程实现部分,动态创建一个idftp组件,将下载的代码全部在这里实现
每当下载开始时再重新登陆,试试看。(在主窗口中,用参数的形式传入登陆的密码、
用户名等等)

pzh509 (2002-04-09 1:49:00)
接受答案了.


win32api的回答最终被接受。
 
话题1780154的标题是: 高分求解FTP多线程下载问题----在线等待(急) (200分)
分类:Internet/TCPIP feichong (2003-04-18 11:22:00)
在Delphi中用idftp或nmftp控件如何对同一远程文件实现多线程下载,是生成多个Tidftp实例
,每个idftp对应一个线程,还是用一个Tidftp建立多个数据连接,每个数据连接对应一个线程

呢?如果是后者,那该如何建立多个数据连接,如何实现。。。
如果哪位大侠有关于FTP多线程下载的源码的话,恳请给我一份!!!
邮箱:emiler@21cn.com QQ:65373285,谢谢!

Headchen (2003-04-18 13:59:00)
看来你对FTP协议还不是非常了解,请首先阅读一下Ftp协议吧。实现多点下载不一定要多线程,
但一定是多个连接,若要多线程下载,则必须首先建立多个线程,在此线程中生成相应的控件,
(一般的情况下在控件内部均生成了窗口,所以一定要在线程中建立控件),然后按照相关的协
议进行操作就可以了,当然还有其他很多问题,比如写文件,多个线程的控制等,不是一个简单
的问题,建议你还是作一个单线程就可以了,现在的网络环境下多点下载实在没有必要。

feichong (2003-04-19 20:07:00)
接受答案了

feichong (2003-04-19 21:30:00)
接受答案了.


Headchen的回答最终被接受。
 
话题2418668的标题是: 初学Indy (100分)
分类:Internet/TCPIP yanscan1 (2004-01-18 20:03:00)
哪位高手介绍一下Indy的基本使用方法

qince (2004-01-18 20:30:00)
问INDY哪方面呢?
INDY基于阻塞多线程的。

江南大米 (2004-01-18 20:44:00)
Indy很多方面的说,你到playicq上找例子,还有一份说明来着![:D]

samboy111 (2004-01-18 20:46:00)
找它的DEMO模拟着练,是捷径。

shaga (2004-01-18 21:15:00)
all demos is the best

yingyigui (2004-01-18 21:26:00)
Internet构件Indy与blocking套接字调用模式
Indy采用blocking模式
Indy采用blocking套接字调用模式。blocking调用类似于读写文件。在进行读写
时,调用的方法在操作完成后才会返回。不同之处在于,网络通讯中的blocking
套接字方法调用可能会花更长的时间,因为远端数据并非时时准备好等待存取(
最快不会超过网络或modem处理数据的速度)。
例如,如果要连接远端,简单地调用connect方法,然后等待返回。如果不连接失
败,则引发一个异常。

Blocking无罪
人们一直不分青红皂白地攻击blocking套接字。与流行的说法相反,blocking套
接字并非一种罪恶。

当Winsock被(从Unix)“移植”到Windows平台,很快有问题发生。在Unix上,
问题很容易解决(类似多线程,不过在Unix上使用独立process代替线程)。Unix
客户端与服务器能够处理process,这些process使用blocking套接字。
Windows3.x不能处理、更不支持多线程。使用blocking接口将会“锁死”用户界
面,使程序不响应。于是,异步扩展特性被增加到WinSock,让Windows3.x可以使
用WinSock,而不会锁死。不过这需要不同的编程方法。因为Windows3.x存在的缺
点而导致blocking套接字不能很好地运作,所以Microsoft和其它一些厂商不遗余
力地攻击blocking套接字。

Win32支持多线程。但在此时,大家的想法已经改变了(比如,开发者坚信
blocking是不好的),而且这种情况无法逆转。所以,对blocking套接字的责难
一直继续。

实际上,blocking套接字是Unix实现套接字的唯一方法。blocking套接字也拥有
其它的优点,而且更有利于实现线程化、安全性更高。目前在Unix上也增加了一
些non-blocking套接字特性。但是,它们以与在Windows中截然不同的方式工作。
没有使用标准,且应用范围不广泛。在Unix上,blocking套接字仍旧在几乎每个
socket应用中存在,且将继续如此。

blocking的好处
1、易于编程——blocking非常易于编程。所有代码能以有序的形式存在于同一位
置。
2、易于移植——由于Unix采用blocking套接字,用blocking套接字的程序更易于
移植到Unix平台。Indy利用该特点,实现了多平台单代码的解决方案。
3、在线程中工作顺利——blocking套接字是串行的,很容易在线程中使用。

blocking的缺点
1、客户端用户界面“死锁”——blocking套接字调用在完成工作之后才返
回。如果在程序主线程中进行此类调用,应用程序将不能正常处理用户界面
消息。这就使用户界面“死锁”,因为在blocking套接字调用把控制权返回
给应用程序消息循环之前,update、repaint和其它消息不能被正常处理。
TIdAntiFreeze
Indy使用一个特殊的组件来解决用户界面死锁问题。把TIdAntiFreeze加入程
序,就可以随意在程序中进行标准的blocking Indy调用,而用户界面也不会死锁。
TIdAntiFreeze工作原理:在内部定时停止堆栈调用、然后调用Application.ProcessMessages。
在外部,对Indy的调用继续阻塞,和没使用TIdAntiFreeze一样正常。

线程化
在blocking套接字中几乎总是使用线程。Non-blocking套接字也可以被线程
化,不过需要额外的处理。而且,相对于blocking套接字而言毫无优势。在
编写blocking套接字服务器时,线程化非常重要。在编写高级的blocking客
户端时也是如此。

线程化的优点
1、优先级——可以调整独立线程优先权。可以为每个服务器任务或是连接配
给适当的CPU时间。
2、封闭性——可保持所有连接,连接之间不会互相干扰。
3、安全性——每个线程可拥有不同的安全属性。
4、多处理器——线程化能自动利用多处理器优势。
5、非串行化——线程化提供真正的并行可能性。假若不线程化,则所有请求
都需要一个单独线程来处理。于是需要把任务切割为多个小块以提高运行速
度。如果某个任务锁住或者执行较慢,其它线程必须等待它结束。任务块结束
后,后一个任务块才能被处理,如此类推。而在线程化的条件下,每个任务均
可作为整个任务来执行,操作系统自动分配CPU时间。

线程Pooling
线程的创建与破坏极耗资源。对于短时连接的服务更是如此。此类服务创建线
程、在很短时间内使用、然后摧毁它。这样,线程会频繁地创建和毁坏。拿
time server或web server来做例子,客户端发送简单的请求,服务器返回简单
回复。使用浏览器浏览一个网页时,有可能需要与服务器进行上百次的连接和
断开操作。线程pooling可以减轻痛苦。它并不在需要时创建和毁坏线程,而是
从已经创建但未使用的列表(pool)中“借出”线程。当线程不再需要,将被抛
回缓冲池,而不会摧毁。缓冲池中的线程被标记为未活动,所以并不消耗CPU循环。
缓冲池的大小可以调整,以适合系统需求。
Indy支持线程pooling。可以用TIdThreadMgrPool组件利用线程pooling。

数以百计的线程
对于一个忙碌的服务器,可能需要数以百计、千计的线程。人们普遍误解如此
多的线程将立刻使系统当掉。其实不然。
对于多数服务器而言,线程存在期的多数时间用于等待数据。在等待blocking
调用时,线程是不活动的。所以,在一个拥有500个线程的服务器中,可能只有
50个同时活动的线程。在我的系统上,330个线程只耗费1%的CPU时间。

线程与全局Section
当线程需要存取数据时,都必须获取对数据的控制权以保护数据完整性。对于
初学线程编程的人士,这恐怕有些头疼。不过多数服务器并不需要全局数据。
每个线程执行隔离的任务。

Indy之道
Indy与你所熟悉的其它Winsock组件不同。如果你曾经使用过其它组件,最好
是彻底忘记它们是如何工作的。几乎所有其它组件都是non-blocking,以异
步方式调用。你需要对事件进行回应,设置状态机,且常常要进行等待循环。
例如,使用其它组件,当进行连接时,必须等待connect事件发生,或者循环
至被告知已连接。而在Indy中,你简单调用connect,然后等待它返回。如果
连接失败,则引发一个异常。使用Indy非常相似于操作文件。代码可以放置于
一个地方,而无需切割到各种事件代码中。

Indy有何不同
简述
1、使用blocking调用
2、不依赖事件——Indy拥有事件(处于提供信息的考虑),但并非必须。
3、被设计为支持线程——无需进行额外的线程化工作。

细节
Indy不光是使用blocking调用,而且也表现为blocking方式。典型的Indy调用:
with IndyClient do begin
Connect; Try
// 你的代码
finally Disconnect; end;
end;
其它组件大概会这样调用:
procedure TFormMain.TestOnClick(Sender: TComponent);
begin
with SocketComponent do begin
Connect; try
while not Connected do begin
if IsError then begin
Abort;
end;
Application.ProcessMessages;

OutData := 'Data To send';
while length(OutData) > 0 do begin
Application.ProcessMessages;
end;
finally Disconnect; end;
end;
end;

procedure TFormMain.OnConnectError;
begin
IsError := True;
end;

procedure TFormMain.OnRead;
var
i: Integer;
begin
i := SocketComponent.Send(OutData);
OutData := Copy(OutData, i + 1, MaxInt);
end;

Indy天生支持线程。在Windows中用Indy编写服务器或客户端与在Unix平台
上编写服务器或客户端相似,甚至更加简单。
典型的Unix服务器有一个或多个“监听”进程,查找客户端请求。对于每个
客户端,都要创建一个新进程。
Indy以简单的方式工作。Windows能较好地处理线程。Indy服务器为每个客户
端锁定一个线程。
Indy服务器建立一个与主线程分离的监听线程。监听线程等待客户端请求。
对于每个连接的客户端,产生一个新线程为其服务。然后,在线程上下文中
引发适当的事件。


ljlljl-79 (2004-01-19 9:09:00)
Delphi 自带的例子很好,你可以在Demo中选几个例子学习一下

DouZheng (2004-01-19 9:15:00)

http://www.indyproject.org/download/Indy9.html
最下面下载 Demo

liboy.com (2004-01-19 9:26:00)
indy 挺简单的嘛,不过主要是说明太少,再用底层一些不知如何下手...
所以改 VC了

乡村月光 (2004-01-19 13:52:00)
去下载html格式的帮助文件,比delphi带的那个详细多了。

app2001 (2004-01-19 14:08:00)
http://www.aidelphi.com/6to23/docu/MyUDP(Delphi6_7).rar
这也有一个,你看看吧

songchuanfang (2004-01-19 14:52:00)
告诉你一个简单的办法吧!ftp 控件其实里面就是封装了ftp实现吗?
你可以用批处理的方法吗?
ftp://ip;
user pwd
list
get 去取文件
dir 列出有的文件


dragonstar (2004-01-27 19:26:00)
你好

黎永欢 (2004-01-28 4:47:00)
还是直接用 winsock api 好,用 indy 你就等着受苦吧。

我正在开发一些网络应用,可以多多交流,我的 e-mail是 wzlyhcn@163.net
UC号是:76754702
没有什么事的话,每日都在线的。
 
接受答案了.
 
后退
顶部