中午提了个问题,看的人都极少,以为是太简单,删了去搜,但仍然没有搜到,还是发贴出来问!关于在线下载的问题!(100分)

  • 主题发起人 主题发起人 del520
  • 开始时间 开始时间
D

del520

Unregistered / Unconfirmed
GUEST, unregistred user!
我用NMHTTP下载网上的文件,正常,但达不到我的要求.

我需要 在下载的时候能显示下载进度条,能显示下载的速度,能够随时中断下载,
最好能支持断点续传!

NMHTTP好像是不行(试了一下午,也找了关于NHTTP的资料,好资达不到要求)?
用什么办法或是控件可以解决我的问题!
 
进度控制:
需要自己分析服务器端的HTTP响应头所发的Content-length或类似的头信息,
得到本次数据将要收到的长度。然后根据已经收到的字节数来确定进度。
断点续传:
客户端的HTTP请求头中的Range头说明了客户端需要接受的服务器端该URL的部分内容,
如果服务器支持,将收到该文件的部分内容而不是整个。
RFC文档里头都写得还算明白的。似乎NMHTTP没封装这么底层的内容。
 
这可不是简单的问题啊
 
to Passion
我的水平还没有那么高,我想能找到个控件,或者是有个例子最好.
实际上我是做一个在线升级部分.

主要是那个下载进度很重要,下载速度和断点续传都不是太重要.

应该有高手用过.

我再继续找资料.....当然谁能帮我最好.....
 
用ics吧..
我用ics就做了进度条
 
下载了一个,但好像没有DEMO,一些属行和方法都不太清楚...
 
1、放置信息文本到网站。
2、使用TNMHTTP从网站信息文本获取文本内容。
3、分析文本解析所需信息。
4、比较程序版本提供升级信息。
首先,放置一个信息文本到自己的网站,这个文本有自己的文件格式,定义如下的格式:
[update]
<ver>1.79.9.25</ver>
<url>http://delphibox.com/softm/3_update.zip</url>
<date>2002-9-25</date>
[/update]
可以将它保存为update.txt文件,使用[]<>的标示符将信息分类,这里包含了程序名、版本、更新日期和下载地址。这里假使上传到http://2ccc.com/update.txt。
然后我们使用TNMHTTP组件从网站获取此文件的内容:
function TForm1.GetUpdateText:String;
begin
NMHTTP1.InputFileMode := FALSE;
NMHTTP1.OutputFileMode := FALSE;
NMHTTP1.ReportLevel := Status_Basic;
NMHTTP1.Get('http://2ccc.com/update.txt'); { 获取网站文本 }
Result:=NMHTTP1.Body;
end;
获取文本以后,要将其中的信息分离,使用了如下的函数:
function TForm1.AnalyseUpdate(Body:String;var Update:TUpdate):Boolean;
var
TmpStr,Ver:String;
function CenterStr(Src:String;Before,After:String):String;
{ 这个函数用来分离两个字符串中间的字符串,
例如 ..('DelphiBox.com','Delphi','.com')=>'Box'。 }
var
Pos1,Pos2:WORD;
begin
Pos1:=Pos(Before,Src)+Length(Before);
Pos2:=Pos(After,Src);
Result:=Copy(Src,Pos1,Pos2-Pos1);
end;
begin
TmpStr:=CenterStr(Body,'update'); { 得到程序名间的升级信息 }
if TmpStr='' then
Result:=False else { 找不到此文件升级信息 }
begin
Ver:=CenterStr(TmpStr,'<ver>','</ver>');
Update.Version:=SeparateVerStr(Ver); { 解析版本 }
Update.Date:=StrToDate(CenterStr(TmpStr,'<date>','</date>')); { 解析日期 }
Update.URL:=CenterStr(TmpStr,'<url>','</url>'); { 解析升级地址 }
Result:=True;
end;
end;
其中TUpdate是我定义的信息的记录格式:
TSimpleVersion=record { 简化的版本信息 }
dwProductVersionMS: DWORD; { 主版本 }
dwProductVersionLS: DWORD; { 辅版本 }
end;
TUpdate=record { 升级信息 }
Name:String[63]; { 程序名 }
Version:TSimpleVersion; { 版本 }
Date:TDate; { 日期 }
URL:ShortString; { 下载地址 }
end;
而SeparateVerStr()函数是将得到字符串形式的升级版本信息转换为简化的版本信息格式:
function SeparateVerStr(s:String):TSimpleVersion;
const
Separator='.'; { 以为'.'分割符 }
var
p,v1,v2,v3,v4:WORD;
begin
if Length(s)=0 then Exit;
p:=pos(Separator, s);
v1:=StrToInt(copy(s,1,p-1));
Delete(s,1,p);
p:=Pos(Separator,s);
v2:=StrToInt(copy(s,1,p-1));
Delete(s,1,p);
p:=Pos(Separator,s);
v3:=StrToInt(copy(s,1,p-1));
Delete(s,1,p);
v4:=StrToInt(s);
Result.dwProductVersionMS:=v1*$10000+v2;
Result.dwProductVersionLS:=v3*$10000+v4;
end;
最后要做的就是比较文件的版本信息,先得到自己的版本,使用如下的函数:
function GetBuildInfo(FName:string):TSimpleVersion; { 得到自身版本信息 }
var
VerInfoSize: DWORD;
VerInfo: Pointer;
VerValueSize: DWORD;
VerValue: PVSFixedFileInfo;
Dummy: DWORD;
begin
VerInfoSize := GetFileVersionInfoSize(PChar(FName), Dummy);
GetMem(VerInfo, VerInfoSize);
GetFileVersionInfo(PChar(ParamStr(0)), 0, VerInfoSize, VerInfo);
VerQueryValue(VerInfo, '/', Pointer(VerValue), VerValueSize);
with VerValue^ do
begin
Result.dwProductVersionMS := dwFileVersionMS; { 主版本 }
Result.dwProductVersionLS := dwFileVersionLS; { 辅版本 }
end;
FreeMem(VerInfo, VerInfoSize);
end;
然后使用如下的函数比较网站的升级版本和现在的版本,如果返回TRUE,说明有新版本文件:
function VersionCheck(OriVer,NewVer:TSimpleVersion):Boolean;
begin
if (OriVer.dwProductVersionMS=NewVer.dwProductVersionMS) then
begin
Result:=OriVer.dwProductVersionLS<NewVer.dwProductVersionLS;
end else
begin
Result:=OriVer.dwProductVersionMS<NewVer.dwProductVersionMS
end;
end;
 
to:热血
我用ics控件写一个FTP服务器程序时发现,无法取得client.username的值。客户端是没有问题的,用ics自带的server程序可以读出用户名,但以下是我写的在客户端连接时判别是不是合法用户的程序却无法取得用户登陆名,用F7跟踪时发现,client.username是空值,但client.getpeerAddr的值取可以正常取得。请问是什么原因?
procedure TForm1.FtpServer1ClientConnect(Sender: TObject;
Client: TFtpCtrlSocket; AError: Word);
begin
if client.UserName ='xxx' then
begin
edit1.Text :=inttostr(ftpserver1.ClientCount)+'个用户已连接';
memo1.Lines.Add(client.GetPeerAddr+' '+client.UserName+' 已连接');
end else
begin
client.Close;
edit1.Text :=inttostr(ftpserver1.ClientCount)+'个用户已连接';
memo1.Lines.Add(client.GetPeerAddr+' '+client.UserName+' 验证未通过');
end;
end;
能指点一下吗?你的源代码能给一份吗?我的信箱:scxxf@21cn.com 多谢!
 
to delphilai
您是delphibox.com的版主吗?我从哪儿下载了一个例子,很不错,对我有很大的启发,我也自己
做了一个类似你那样的.ini文件,用于存放我的升级信息,但是,我那个实际的升级文件比较大
有好几M,我用NMHTTP来下载这个东西肯定需要时间,所以我必须使用一个进载进度条.但我发
现用NMHTTP好像达不到我的要求,经热血建议我用ICS,看了它自带的一些例子,但还是没有发
现好的办法.
ICS里面有个HTTPGET好像有点不准确.
谁还有更好的办法....
 
搞定了,用ICS搞定,感谢热血提供信息
方法:在ICS里面有个httpGet例子,刚才仔细看了一下,搞明白了,做成了下载进度条!
其实很简单,昨晚上是不是头有点糊..:(

发分!!
 
多人接受答案了。
 
to:del520
用http的方式好象无法验证用户的合法性,
能把你的程序发一份给我学习、学习吗?scxxf@21cn.com
 
后退
顶部